可能你还没见过这个东西是个啥,其实他就是类似于setTimeout和setInterval,然而它与setTimeout和setInterval又有所不同,requestAnimationFrame不需要设置时间间隔。这有什么好处呢?requestAnimationFrame有何神奇之处?本文将详细介绍HTML5新增的定时器requestAnimationFrame。
计时器一直是javascript动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化。
大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms。
而setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行。
requestAnimationFrame采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
requestAnimationFrame的用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行
上面这段代码其中结果1则是requestAnimationFrame返回值,执行一遍返回1,如此类推,你可能疑惑为什么console.log(timer);中的timer没有加()也能执行,这得回到文章头部说到的你可以理解为requestAnimationFrame就是个定时器,定时器自然不需要手动去触发执行
1 2 3 4 5 | //控制台什么都不输出 var timer = requestAnimationFrame(function(){ console.log(0); }); cancelAnimationFrame(timer); |
1 2 3 4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 倒计时循环 * @private */ _CountDownLoop() { var currStemp = new Date(); currStemp = new Date(currStemp.getTime() + this.offset); //如果结束时间戳减去当前时间时间戳小于等于0则设置倒计时结束标识为true if (this.endStemp.getTime() - currStemp.getTime() <= 0) { this.isEnd = true; } //如果结束则调用结束回调 if (this.isEnd === true) { // console.log('countdown end'); this.endcallback.apply(this, [this.endurl]); } else { this._render(currStemp); var that = this; requestAnimationFrame(function() { that._CountDownLoop(); }); } } |
上面示例中我们可以看到,通过requestAnimationFrame不断的自己调用自己,实现高频度刷新倒计时,从而解决了页面切换窗口等传统setTimeout和setInterval假死问题。
支付宝扫一扫打赏
微信扫一扫打赏
共 0 条评论关于"神奇的requestAnimationFrame解决传统定时器bug"
最新评论