因使用setInterval定时改变scrollTop以达到自动滚动效果,列表会出现明显抖动,所以在这里使用requestAnimationFrame来实现滚动效果
使用:
id:当前滚动元素的id
interval:滚动时间
backtrack:触底返回方式(true---缓慢返回;false----1秒到顶)
mouse:鼠标悬停
//引入
import { autoScroll } from '@/utils/autoScroll'
//使用
onMounted(async () => {
//开始滚动
setTimeout(() => {
const scroll = new autoScroll({
id: '#scrollContainer',
interval: 2000,
backtrack: true,
mouse: true
})
scroll.start()
}, 3000)
})
新建:autoScroll.js
export class autoScroll {
#animate;
#id;
#interval;
#backtrack;
#direction = 'toBottom';
#mouse;
#timer = null;
constructor({ id = '', interval = 2000, backtrack = false, mouse = true }) {
this.#id = id
this.#interval = interval
this.#backtrack = backtrack
this.#mouse = mouse
}
start() {
const animateFn = () => {
const dom = document.querySelector(this.#id)
if (dom.scrollHeight <= dom.clientHeight) {
return
}
if (dom) {
this.#direction === 'toTop' && (dom.scrollTop -= 1)
this.#direction === 'toBottom' && (dom.scrollTop += 1)
if (dom.scrollTop === 0) {
this.clear()
this.#direction = 'toBottom'
this.move(animateFn, this.#interval)
} else if (dom.scrollHeight - dom.clientHeight <= dom.scrollTop) {
this.clear()
if (this.#backtrack) {
this.#direction = 'toTop'
this.move(animateFn, this.#interval)
} else {
dom.scrollTo({
top: 0,
behavior: 'smooth'
})
this.move(animateFn, this.#interval)
}
} else {
this.move(animateFn)
}
}
}
setTimeout(() => {
animateFn()
this.#mouse && this.mouseListen(animateFn)
}, 0);
}
mouseListen(animateFn) {
const dom = document.querySelector(this.#id)
dom.addEventListener('mouseover', () => this.clear())
dom.addEventListener('mouseleave', animateFn)
}
move(animateFn, time) {
time && !this.#timer && (this.#timer = setTimeout(() => {
this.#animate = requestAnimationFrame(animateFn);
this.#timer = null
}, time))
!time && !this.#timer && (this.#animate = requestAnimationFrame(animateFn))
}
clear() {
cancelAnimationFrame(this.#animate)
}
}