vue3 实现简易滚动效果

vue 是实现简易滚动效果

前言

在做h5页面时需要实现索引栏一样的效果,但直接引用组件会影响之前的整体布局。 思考之后决定使用
vant-ui Tab滚动效果来实现,经过简化vant源码分享给大家。

动画效果的实现主要通过 raf 中的requestAnimationFrame

requestAnimationFrame

requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧>对网页进行重绘。

设置这个API的目的是为了让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)>能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个>API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘。

requestAnimationFrame的优势,在于充分利用显示器的刷新机制,比较节省系统资源。显示器有固定>的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次,requestAnimationFrame的>基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘。此外,使用这个API,一旦>页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了CPU、GPU和电力。

不过有一点需要注意,requestAnimationFrame是在主线程上完成。这意味着,如果主线程非常繁忙,requestAnimationFrame的动画效果会大打折扣。
requestAnimationFrame使用一个回调函数作为参数。这个回调函数会在浏览器重绘之前调用。

html
 <button @click="scrollTopTo(1000)">点击</button>

js

let inBrowser = typeof window !== 'undefined'
function raf(fn) {
    return inBrowser ? requestAnimationFrame(fn) : -1
}

const scrollTopTo = (
    to, //需要滚动到的位置
    scroller = window,//需要滚动的窗口 默认是window窗口 
    duration = .3,  //默认延迟时间0.3s
    callback = () => {} //回调函数 可以通过回调函数阻止滚动进行时其他事件触发
) => {
    let current = getScrollTop(scroller) //获取当前窗口位置
    const isDown = current < to
    const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16)
    const step = (to - current) / frames
   
    function animate() {
    	//使用递归 + 或 -
        current += step 
        if ((isDown && current > to) || (!isDown && current < to)) {
            current = to
        }
        setScrollTop(scroller, current)  // 改变窗口位置
        if ((isDown && current < to) || (!isDown && current > to)) {
            raf(animate)
        } else if (callback) {
            raf(callback)
        }
    }
    animate()
}

const getScrollTop = (el) => {
    const top = 'scrollTop' in el ? el.scrollTop : el.pageYOffset
    return Math.max(top, 0)
}

const setScrollTop = (el, value) => {
    if ('scrollTop' in el) {
        el.scrollTop = value
    } else {
        el.scrollTo(el.scrollX, value)
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值