window.requestAnimationFrame(func) 这个方法接受一个函数为参数,该函数会在浏览器下一次重绘前调用,开发人员可以用这个特性结合递归来更好的操作动画。
参数 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。返回值 返回一个 long 整数,请求 ID ,是回调列表中唯一的标识。 你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。requestAnimationFrame(fucntion): 执行某个方法 cancelAnimationFrame(ID): 清除指定动画
使用requestAnimationFrame,浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。
requestAnimationFrame与setInterval都可以实现循环触发事件,但是setInterval是基于时间的,而requestAnimationFrame是基于帧数的,requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,这样就会减少重绘和回流,使得动画更流畅;
大多浏览器都是在60帧,即一秒最多刷新60次
窗口没激活时(切换到后台时),动画将停止,这就意味着更少的的cpu,gpu和内存使用量。;
窗口没激活时(切换到后台时),动画将停止的使用场景: 在A窗口调用requestAnimationFrame实现动画,可以看到动画在执行,在此时,如果切换到浏览器的B窗口,那么动画暂停,再切换回来后动画又将继续。
因浏览器不同,为了兼容性,有三种格式的:
requestID = window.requestAnimationFrame(callback); requestID = window.mozRequestAnimationFrame(callback); requestID = window.webkitRequestAnimationFrame(callback); requestID = window.msRequestAnimationFrame(callback);网上大神的兼容写法
(function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }());简单说明: 1-定义了一个立即执行函数,形成具备作用域,避免污染全局空间。 2-将功能函数挂在了window. 3-利用setTimeout和clearTimeout的异步实现相应的功能,不是为一种很好的结局方案。
参考链接:https://blog.csdn.net/w2765006513/article/details/53843169 参考链接:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame