var i = 0 var requestID = 0; var step = function(timer) { console.log(i); i ++; if (i > 100) { cancelAnimationFrame(requestID) } requestID = requestAnimationFrame(step); } requestID = requestAnimationFrame(step);
(function() { var vendors = ['webkit', 'moz']; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] || window[vp+'CancelRequestAnimationFrame']); } window.requestAnimationFrame = window.requestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; }());
上面这个实现比较简单,主要是用各个浏览器的私有方法,并对不存在该私有方法的浏览器采用 setTimeout 实现,其实现实际上和 requestAnimationFrame 并不一致,但已经可以保证应用在大多数的场合之下了,更加完善的被 Erik Möller 实现的 polyfill 代码如下:
// Adapted from https://gist.github.com/paulirish/1579671 which derived from // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
// MIT license
if (!Date.now) Date.now = function() { returnnewDate().getTime(); };
(function() { 'use strict'; var vendors = ['webkit', 'moz']; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] || window[vp+'CancelRequestAnimationFrame']); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); returnsetTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }());