1、代码组件(vue 封装)
<template>
<div class="custom-list" ref="scrollBody" @mouseenter="mouseenterFunc" @mouseleave="mouseleaveFunc" @mousewheel="mousewheelFunc">
<div class="list-body" :class="{
'list-body2': isHorizontal,
canScroll:!isCanScroll
}" ref="listBody" :style="{ transform: getScrollDistance() }">
<slot></slot>
</div>
<div class="list-body" :class="{
'list-body2': isHorizontal
}" ref="tBody" v-if="isCanScroll" :style="{ transform: getScrollDistance() }">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
steep: {
//滚动速度
type: Number,
default: 1,
},
scrollDirection: {
//滚动方向
type: String,
default: 'top',
},
isRoller: {
//是否可以滑轮滚动
type: Boolean,
default: true,
},
rollerScrollDistance: {
//滑轮滚动的距离
type: Number,
default: 20,
},
isRoll: {
//是否可以滑轮滚动
type: Boolean,
default: true,
},
data: Array,
},
computed: {
isHorizontal() {
return this.scrollDirection === 'left' || this.scrollDirection === 'right'
},
},
data() {
return {
scrollDistance: 0, //滚动距离
bodyHeight: 0, //滚动容器高度
bodyWidth: 0, //滚动容器宽度
listHeight: 0, //列表高度
listWidth: 0, //列表宽度
isStop: false,
animationFrame: null,
scrollBody: null,
listBody: null,
isCanScroll: true,
}
},
mounted() {
this.initData()
},
methods: {
initData() {
this.scrollDistance = 0
this.isCanScroll = !0
this.scrollBody = this.$refs.scrollBody
this.bodyHeight = this.scrollBody?.clientHeight
this.bodyWidth = this.scrollBody?.clientWidth
this.listBody = this.$refs.listBody
this.listHeight = this.listBody?.clientHeight
this.listWidth = this.listBody?.clientWidth
if ((this.bodyHeight !== 0 && this.listHeight !== 0 && this.listHeight >= this.bodyHeight) || (this.bodyWidth !== 0 && this.listWidth !== 0 && this.listWidth >= this.bodyWidth)) {
this.isCanScroll = true
this.start()
} else {
this.isCanScroll = false
}
},
start() {
return
let isScrollFunc = (bodySize, listSize) => {
if (bodySize > listSize || this.steep == 0) {
this.scrollDistance = 0
this.isCanScroll = !1
}
}
this.isStop = !1
//判断是否可以滚动
if (!this.isHorizontal) {
isScrollFunc(this.bodyHeight, this.listHeight)
} else {
isScrollFunc(this.bodyWidth, this.listWidth)
}
if (this.isCanScroll) {
this.run()
}
//判断是否可以滚动函数
},
run() {
//清空动画
this.clearAnimation()
this.animationFrame = window.requestAnimationFrame(() => {
//滚动主逻辑函数
let main = (listSize, bodySize) => {
let tempScrollDistance = Math.abs(this.scrollDistance)
if (this.scrollDistance < 0) {
let cc = 2 * listSize - bodySize
if (tempScrollDistance > cc) {
this.scrollDistance = -(listSize - bodySize)
}
} else {
this.scrollDistance = -listSize
}
}
//根据滚动方向判断使用高度或宽度控制效果
if (!this.isHorizontal) {
main(this.listHeight, this.bodyHeight)
} else {
main(this.listWidth, this.bodyWidth)
}
//判断滚动值
if (!this.isStop) {
if (this.scrollDirection === 'top' || this.scrollDirection === 'left') {
this.scrollDistance -= this.steep
} else if (this.scrollDirection === 'bottom' || this.scrollDirection === 'right') {
this.scrollDistance += this.steep
}
this.run()
}
})
},
stop() {
this.isStop = !0
this.clearAnimation()
},
//获取滚动样式
getScrollDistance() {
let style
if (!this.isHorizontal) {
style = 'translate(0px, ' + this.scrollDistance + 'px)'
} else {
style = 'translate(' + this.scrollDistance + 'px,0px)'
}
return style
},
clearAnimation() {
if (this.animationFrame) {
cancelAnimationFrame(this.animationFrame)
this.animationFrame = null
}
},
mouseenterFunc() {
this.stop()
},
mouseleaveFunc() {
this.start()
},
mousewheelFunc(e) {
if (!this.isCanScroll || !this.isRoller) {
return false
}
let dis = e.deltaY
if (dis > 0) {
this.scrollDistance -= this.rollerScrollDistance
} else {
this.scrollDistance += this.rollerScrollDistance
}
this.run()
},
},
}
</script>
<style lang="scss">
.custom-list {
white-space: nowrap;
font-size: 14px;
overflow: hidden;
height: 100%;
}
.list-body {
overflow: hidden;
white-space: nowrap;
font-size: 14px;
}
.canScroll {
height: 100%;
overflow: auto;
}
.list-body2 {
display: inline-block;
}
</style>
2、代码引用
<com-auto-scroll-mouse class="WH table-td" v-if="enterListTab.length" :data="enterListTab" :steep="0.5" scrollDirection="top" :isRoll="isRoll" :isRoller="true" :rollerScrollDistance="50">
<div class="width flex row-between padding5" id=" " :class="index % 2 == 0 ? 'sbgWe' : 'bgWeight'" style="color: black" v-for="(item, index) in enterListTab" :key="index">
<div class="padding5 flex grad1">{{ index + 1 }}</div>
<div>{{ item.enterName }}</div>
<div @click="handleMap(item)"><img src="~@/assets/img/homeFirst/map.png" alt="" /></div>
</div>
</com-auto-scroll-mouse>