window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
当你准备更新动画时你应该调用此方法。这将使浏览器在下一次重绘之前调用你传入给该方法的动画函数(即你的回调函数)。回调函数执行次数通常是每秒60次,但在大多数遵循W3C建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame()
运行在后台标签页或者隐藏的<iframe>
里时,requestAnimationFrame()
会被暂停调用以提升性能和电池寿命。
回调函数会被传入DOMHighResTimeStamp
参数,DOMHighResTimeStamp
指示当前被 requestAnimationFrame()
排序的回调函数被触发的时间。在同一个帧中的多个回调函数,它们每一个都会接受到一个相同的时间戳,即使在计算上一个回调函数的工作负载期间已经消耗了一些时间。该时间戳是一个十进制数,单位毫秒,最小精度为1ms(1000μs)。
语法:window.requestAnimationFrame(callback);
参数:callback
下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp
参数,该参数与performance.now()
的返回值相同,它表示requestAnimationFrame()
开始去执行回调函数的时刻。
返回值:一个 long
整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame()
以取消回调函数。
示例一:
var start = null; var element = document.getElementById(‘SomeElementYouWantToAnimate‘); element.style.position = ‘absolute‘; function step(timestamp) { if (!start) start = timestamp; var progress = timestamp - start; element.style.left = Math.min(progress / 10, 200) + ‘px‘; if (progress < 2000) { window.requestAnimationFrame(step); } } window.requestAnimationFrame(step);
示例二:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>2.2 移动端动画</title> <style> * { padding: 0; margin: 0; } .box { width: 100px; height: 100px; background-color: red; /*position: absolute; transition: left margin-left 1s;*/ /*transition: transform 1s;*/ } </style> </head> <body> <button id="btn">start</button> <div id="box" class="box"></div> <script> // var boxEl = document.getElementById(‘box‘), // btnEl = document.getElementById(‘btn‘); // var dest = window.innerWidth - 100; // btnEl.addEventListener(‘click‘, function () { // move(boxEl, dest); // }, false); // function move(el, position) { // el.style.transform = ‘translate3d(‘ + position +‘px, 0, 0)‘; // } var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function (fn) { setTimeout(fn, 16); }; var boxEl = document.getElementById(‘box‘), btnEl = document.getElementById(‘btn‘); var dest = window.innerWidth - 100, speed = 10, position = 0; btnEl.addEventListener(‘click‘, function () { requestAnimationFrame(step); }, false); function move(el, position) { el.style.transform = ‘translate3d(‘ + position +‘px, 0, 0)‘; } function step() { if (position < dest) { position += speed; move(boxEl, position); requestAnimationFrame(step); } else { position = dest; move(boxEl, position); } } </script> </body> </html>
实现js动画最好的是requestAnimationFrame:
requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
示例三:
var dis =0; function animation(){ requestAnimationFrame(function(){ div.style.left = ++dis; if(disx<50) animation(); }) } animation();