一、requestAnimationFrame() 方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
由系统来决定回调函数的执行时机 如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次
它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
优点:
1.浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。
2.在一个浏览器标签页里运行一个动画,当这个标签页不可见时(页面被tab切换,或者最小化之后),浏览器会暂停它,这会减少CPU,内存的压力,节省电池电量。
二、setTimeout
利用seTimeout实现的动画在某些低端机上会出现卡顿、抖动的现象,这种现象的产生有两个原因:
1.setTimeout的执行时间并不是确定的。在Javascript中, setTimeout 任务被放进了异步队列中,只有当主线程上的任务执行完以后,才会去检查该队列里的任务是否需要开始执行,因此 setTimeout 的实际执行时间一般要比其设定的时间晚一些。
2.刷新频率受屏幕分辨率和屏幕尺寸的影响,因此不同设备的屏幕刷新频率可能会不同,而 setTimeout只能设置一个固定的时间间隔,这个时间不一定和屏幕的刷新时间相同。
//动画持续转动
let obox=document.getElementsByClassName('box1')[0]; let deg=0; function test(){ if(deg==360){ deg=0; } deg+=5; console.log(deg); obox.style.transform=`rotate(${deg}deg)`; window.requestAnimationFrame(test); } window.requestAnimationFrame(test);
三、mousemove, scroll 这类事件,requestAnimationFrame 会在一帧内被多次调用,
需要管理回调函数,防止重复绘制动画。
let flag=true; const onScroll = e => { if (!flag) return; flag = false; window.requestAnimationFrame(timestamp => { flag = true; console.log(1111111) // animation(timestamp); }) } window.addEventListener('scroll', onScroll);