使用vue-seamless-scroll插件时发现当一组列表滚动完之后会留有一些空白在页面上,如下图
于是自己封装了一个组件,内包括鼠标移入、鼠标移出、首尾相应等事件,具体如下,可直接赋值运行
<template>
<div class="scrollList">
<h2>无缝滚动</h2>
<div @mousemove="testMove" @mouseleave="testMend">
<div ref="roll" style="height: 110px;overflow: hidden;margin:20px;">
<slot>
<li>模拟标题1</li>
<li>模拟标题2</li>
<li>模拟标题3</li>
<li>模拟标题4</li>
<li>模拟标题5</li>
</slot>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
timer: null, //定时器
roll: null, //获取容器的值
}
},
methods: {
//鼠标移入事件
testMove() {
clearTimeout(this.timer)
},
//鼠标移出事件
testMend() {
this.start()
},
//开启定时器方法
start() {
//清除定时器
clearTimeout(this.timer)
//定时器触发周期,移动速度
let speed = 50
this.timer = setInterval(() => {
//获取绑定的容器
this.roll = this.$refs.roll
let test1 = this.roll
//判断组件是否渲染完成
if (test1.offsetHeight == 0) {
test1 = this.roll
} else {
//如果列表数量过少不进行滚动
if (test1.childNodes.length < 6) {
clearTimeout(this.timer)
return;
}
//组件进行滚动
test1.scrollTop += 1
//判断滚动条是否滚动到底部
if (test1.scrollTop == (test1.scrollHeight - test1.clientHeight)) {
//获取组件第一个节点
let a = test1.childNodes[0]
//删除节点
test1.removeChild(a)
//将该节点拼接到组件最后
test1.append(a)
}
}
}, speed)
},
},
mounted() {
this.$nextTick(() => {
// 在挂载完成后执行回调函数
this.start();
});
},
//组件销毁前需清除定时器
beforeDestroy() {
//清除定时器
clearTimeout(this.timer)
},
//组件销毁后需清除定时器
destroyed() {
//清除定时器
clearTimeout(this.timer)
},
}
</script>
<style lang="scss" scoped>
.scrollList {
width: 100%;
height: 100%;
h2 {
text-align: center;
}
}
</style>
原理:
主要就是通过通过计时器不断的给获取到的容器增加它的自身高度,在与可视高度为0时,将容器内的第一个子元素添加到容器底部,从而达到首尾呼应,Vue3版本的见下一篇文章