vue組件實現(xiàn)列表自動無限循環(huán)的方法
更新時間:2023年11月14日 09:35:55 作者:The?ever?Boy
最近剛好有個功能需要實現(xiàn)列表的無限循環(huán)滾動,這篇文章主要給大家介紹了關于vue組件實現(xiàn)列表自動無限循環(huán)的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
前述:
用過vue-seamless-scroll插件,手動滾動列表到底部出現(xiàn)了空白現(xiàn)象,某些表現(xiàn)不符合項目場景,故自己寫了一個自己用的組件,如果有人需要可以直接拿去用,如有不足請指教勿噴!
主要功能:
- 列表自動無限循環(huán)滾動
- 鼠標移入停止?jié)L動,移出繼續(xù)滾動
- 待滾動內(nèi)容高度未鋪滿并超過容器高度時不滾動
- 支持滾動速度、單次滾動時間間隔、單次滾動高度,三個參數(shù)控制
- 可自己手動滾動列表
效果圖 :

組件代碼:
<template>
<div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
<div class="scroll-inner-box" ref="scrollBox">
<div class="scroll-item-box" ref="scrollItemBox">
<slot></slot>
</div>
<div v-if="showSecond" class="scroll-item-box">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: "my-auto-scroll",
props: {
list: {
type: Array,
default: () => [
{ name: "張三1" },
{ name: "張三2" },
{ name: "張三3" },
{ name: "張三4" },
{ name: "張三5" },
{ name: "張三6" },
{ name: "張三7" },
{ name: "張三8" },
{ name: "張三9" },
{ name: "張三10" },
],
},
speed: {
type: Number,
default: 0.1,
},
//滾動作單步運動時的單純運動距離
singleHeight: {
type: Number,
default: 0,
},
//單步運動的時間間隔
waitTime: {
type: Number,
default: 0,
},
},
data() {
return {
rafId: null,
y: 0,
showSecond: false,
controleHeight: 0,
};
},
watch: {
list: {
handler(newVal) {
var that = this;
this.$nextTick(() => {
console.log(newVal);
if (newVal && newVal.length > 0) {
let scrollBox = that.$refs.scrollBox;
let outer = that.$refs.outer;
if (this.myReq) {
cancelAnimationFrame(this.myReq);
}
// 開啟動畫
if (this.canRun()) this.reqAnimationFrame();
// this.reqAnimationFrame();
// 手動滾動到底部時滾動條重置到最上邊,同時滾動盒子重置為top:0
outer.addEventListener("scroll", function () {
if (
outer.scrollTop + outer.clientHeight + 4 >=
outer.scrollHeight
) {
outer.scrollTop = 0;
that.y = 0;
scrollBox.style.top = 0;
}
});
}
});
},
deep: true,
immediate: true,
},
},
mounted() {
window.addEventListener("resize", this.listenResizeFn);
},
methods: {
listenResizeFn() {
cancelAnimationFrame(this.myReq);
if (this.canRun()) this.reqAnimationFrame();
},
onMouseover() {
clearTimeout(this.timer);
cancelAnimationFrame(this.myReq);
},
onMouseleave() {
if (this.canRun()) this.reqAnimationFrame();
},
canRun() {
let scrollItemBox = this.$refs.scrollItemBox;
let scrollBox = this.$refs.scrollBox;
let outer = this.$refs.outer;
// 開啟動畫條件:滾動盒子(scrollBox)高度高于外層容器(outer)高度
if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
this.showSecond = false;
outer.scrollTop = 0;
this.y = 0;
scrollBox.style.top = 0;
return false;
} else {
this.showSecond = true;
return true;
}
},
//獲取dom元素的高度:content+padding+margin+border
getComputedHeight(dom) {
let computedStyle = getComputedStyle(dom);
let computedHeight =
dom.offsetHeight +
parseFloat(computedStyle.marginTop) +
parseFloat(computedStyle.marginBottom);
return computedHeight;
},
reqAnimationFrame() {
//外層容器
let outer = this.$refs.outer;
//滾動盒子
let scrollBox = this.$refs.scrollBox;
//滾動盒子下邊的第一個scroll-item-box,
let scrollItemBox = this.$refs.scrollItemBox;
//滾動速度
this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
//取第一個scrollItemBox高度
let definedHeight = this.getComputedHeight(scrollItemBox);
//持續(xù)滾動
this.y = this.y + this.speed;
scrollBox.style.top = -this.y + "px";
//====添加滾動間隔控制====開始
if (this.singleHeight >= 20 && this.waitTime > 500) {
if (this.controleHeight >= this.singleHeight) {
cancelAnimationFrame(this.myReq);
this.controleHeight = 0;
this.timer = setTimeout(() => {
if (this.canRun) this.reqAnimationFrame();
}, this.waitTime);
return;
} else {
// 一次移動高度未達到指定距離繼續(xù)執(zhí)行動畫
this.controleHeight += this.speed;
}
}
//====添加滾動間隔控制====結(jié)束
//當滾動到第一個scroll-item-box高度時scrollBox重置為top:0,視覺上是無縫滾動
if (this.y >= definedHeight) {
this.y = 0;
}
this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
},
},
destroyed() {
window.removeEventListener("resize", this.listenResizeFn);
cancelAnimationFrame(this.myReq);
if (this.timer) clearTimeout(this.timer);
},
};
</script>
<style lang="scss">
.scroll-outer {
height: 100%;
overflow-x: hidden;
position: relative;
&::-webkit-scrollbar {
width: 0.3vw;
}
&:hover::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
border-radius: 0.1vw;
background-color: #295099;
opacity: 1;
// display: none;
}
&:hover::-webkit-scrollbar-thumb {
opacity: 1;
border-radius: 0.1vw;
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
background-color: #0ba9ea;
}
}
.scroll-inner-box {
height: auto;
position: absolute;
width: 100%;
top: 0;
left: 0;
}
</style>
使用示例:
import autoScroll from "@/components/autoScroll";
<autoScroll :list="list" :speed="0.5" :waitTime="2000" :singleHeight="100">
<div class="t-item" v-for="(item,index) in list" :key="index">
<div class="tvalue" style="flex: 0 0 30%;">{{ item.jgjc }}</div>
<span class="tvalue">{{ item.total||'--' }}</span>
<span class="tvalue" style="color:#0FCBDE">{{ item.ypc||'--' }}</span>
<span class="tvalue" style="color:#F15730">{{ item.zlz||'--' }}</span>
<span class="tvalue" style="color:#17DB68">{{ item.zlwc||'--' }}</span>
</div>
</autoScroll>使用注意:
- autoScroll容器默認是占外層容器寬高百分百,要自己在autoScroll外層加個容器
- 參數(shù)waitTIme和singleHeight同時存在,才能出現(xiàn)滾動動畫間隔執(zhí)行的效果
- 樣式用了sass,如果有問題可以去掉或者導入sass
總結(jié)
到此這篇關于vue組件實現(xiàn)列表自動無限循環(huán)的文章就介紹到這了,更多相關vue列表自動無限循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在vue和element-ui的table中實現(xiàn)分頁復選功能
這篇文章主要介紹了在vue和element-ui的table中實現(xiàn)分頁復選功能,本文代碼結(jié)合圖文的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12

