1、vue3 闭包滚动函数的使用
js 调用也基本雷同
// 滚动Tab组件
const scoreTabRef = ref()
// 滚动的选项
const scrollOption = ref({
// 滚动的Dom元素
scrollDom: null,
// 滚动的时间间隔
scrollInterval: 1500,
// 滚动的距离
scrollSep: 100,
// 滚动历时时间
scrollDuration: 1000
})
const autoScroll = ref()
onMounted(() => {
// 初始化,获取某个组件的滚动的dom元素(设置了高度的div)
scrollOption.value.scrollDom = scoreTabRef.value.$el.querySelector('.v-table__wrapper')
// 闭包函数,传输滚定的选项
autoScroll.value = tool.autoScroll(scrollOption.value)
// 执行闭包函数的滚动方法
autoScroll.value.startScroll()
})
onUnmounted(() => {
// 销毁页面,也销毁闭包内的定时器
autoScroll.value.destoryScroll()
})
vue3各组件内互不影响
2 定义 tool.js 的平滑滚动闭包函数
闭包函数仅需关心参数
export const tool = {
// 自动滚动闭包函数
autoScroll: (scrollOptionParam) => {
// 滚动选项
let scrollOption = Object.assign(
{
// 滚动的Dom元素
scrollDom: null,
// 滚动的时间间隔
scrollInterval: 1500,
// 滚动的距离
scrollSep: 50,
// 滚动历时时间
scrollDuration: 1000
},
scrollOptionParam
)
// 滚动临时结果
let scrollResult = {
scrollTimer: null,
pauseTimer: null
}
// 实际滚动方法
const scrollFun = () => {
// 如果定时器存在
if (scrollResult.scrollTimer) {
// 则先清除
clearInterval(scrollResult.scrollTimer)
scrollResult.scrollTimer = null
}
scrollResult.scrollTimer = setInterval(() => {
// 获取当前滚动条距离顶部高度
const scrollTop = scrollOption.scrollDom.scrollTop
const temp = scrollTop + scrollOption.scrollSep
smoothScroll(scrollOption.scrollDom, temp, scrollOption.scrollDuration)
}, scrollOption.scrollInterval)
}
// 平滑滚动效果
const smoothScroll = (element, targetY, duration) => {
const startY = element.scrollTop
const distance = targetY - startY
const startTime = performance.now()
const scrollHeight = element.scrollHeight
const clientHeight = element.clientHeight
const canScroll = scrollHeight - clientHeight
function scroll(currentTime) {
const elapsed = currentTime - startTime
const progress = Math.min(elapsed / duration, 1)
const easeProgress = progress * (2 - progress)
const currentY = startY + distance * easeProgress
element.scrollTop = currentY
// 如果已经达到目标位置或者达到持续时间,停止动画
if (progress < 1 && Math.abs(currentY - targetY) > 1) {
requestAnimationFrame(scroll)
} else {
element.scrollTop = targetY // 确保最终位置
}
// 距离顶部高度 大于等于 滚动长度
if (canScroll <= targetY) {
// 滚动到底部 停止定时器
clearInterval(scrollResult.scrollTimer)
scrollResult.scrollTimer = null
scrollOption.scrollDom.scrollTop = 0
// 一秒后重开定时器
setTimeout(() => {
scrollFun()
}, 1000)
}
}
requestAnimationFrame(scroll)
}
const pauseScroll = () => {
// 定时器不为空
if (scrollResult.scrollTimer) {
// 清除定时器
clearInterval(scrollResult.scrollTimer)
scrollResult.scrollTimer = null
// 一秒钟后重新开始定时器
scrollResult.pauseTimer = setTimeout(() => {
scrollFun()
}, 2000)
}
}
return {
startScroll: () => {
const scrollHeight = scrollOption.scrollDom.scrollHeight
const clientHeight = scrollOption.scrollDom.clientHeight
const scroll = scrollHeight - clientHeight
// 滚动长度为0,则无法实现自动滚动
if (scroll === 0) {
return
}
// 触发滚动方法
scrollFun()
// 去除点击监听
scrollOption.scrollDom.removeEventListener('click', pauseScroll)
// 重设点击监听
scrollOption.scrollDom.addEventListener('click', pauseScroll, false)
},
destoryScroll: () => {
// 清理定时器
clearTimeout(scrollResult.pauseTimer)
scrollResult.pauseTimer = null
clearInterval(scrollResult.scrollTimer)
scrollResult.scrollTimer = null
// 清理点击监听
scrollOption.scrollDom.removeEventListener('click', pauseScroll)
}
}
}
}