requestAnimationFrame() 方法

@[TOC](requestAnimationFrame() 方法)

一、基本使用

1.基本介绍

window.requestAnimationFrame() 主要是用来实现动画的时候使用的,不管是移动动画还是数字增长动画,使用这个api可以让你的动画看起来非常平滑,因为它是要求浏览器在下次重绘之前调用指定的回调函数更新动画。
它和setInterval的区别是不需要我们去设置时间间隔,因为他会根据我们的屏幕刷新率来决定何时执行回调的内容。

2.创建任务

语法:requestAnimationFrame(callback)
callback是你需要执行的回调函数,回调函数会传入 DOMHighResTimeStamp 参数,该参数与 performance.now() 的返回值相同,它表示 requestAnimationFrame() 开始执行回调函数的时刻
例如:

  window.onload = () => {
    
    
    const test1 = (timeStamp) => {
    
    
      console.log('requestAnimationFrame---', timeStamp)
      window.requestAnimationFrame(test1)
    }
    window.requestAnimationFrame(test1)
  }

注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用 requestAnimationFrame()。requestAnimationFrame() 是一次性的
执行结果:
在这里插入图片描述
可以看到,执行间隔大约为17毫秒,即60hz的刷新率下。

3.清除任务

就像clearInterval一样,我们可以执行window.cancelAnimationFrame()来清除任务。
requestAnimationFrame()会返回一个 long 整数,是回调列表中唯一的标识。是个非零值,没有别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数的执行。
例如:

let requestAnimation = undefined
  window.onload = () => {
    
    
    const test1 = (timeStamp) => {
    
    
      console.log('requestAnimationFrame---', timeStamp)
      requestAnimation = window.requestAnimationFrame(test1)
      window.cancelAnimationFrame(requestAnimation)
    }
    window.requestAnimationFrame(test1)
  }

执行结果:
在这里插入图片描述
回调中的 requestAnimationFrame 就被取消了

二、优势所在

我们使用setInterval也可以达到类似的效果,那么requestAnimationFrame 的优势在哪里?

1.平滑执行

requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。所以每次回调中的内容执行的间隔都是和用户屏幕刷新率相关的,这样动画看起来就会非常平滑。使用setInterval不可避免会有些抖动的现象出现

2.执行间隔稳定

了解微任务、宏任务相关知识的同学应该知道,setInterval在任务队列中是会被阻塞的,这就导致即使我们设定了17毫秒,实际上每次的间隔并不会是刚好17毫秒。但是requestAnimationFrame可以保证在每一帧都完成回调中的内容渲染。

3.性能提升

requestAnimationFrame是由浏览器专门为实现动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU和电池的开销。这也能避免使用setInterval的时候出现任务积压的问题。

猜你喜欢

转载自blog.csdn.net/weixin_43845090/article/details/131069914