与setTimeoutsetInterval不同,requestAnimationFrame不需要设置时间间隔。这有什么好处呢?为什么requestAnimationFrame被称为神器呢?本文将详细介绍H5新增的定时器requestAnimationFrame

引入

  计时器一直是javascript动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化

  大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是lOOOms/60,约等于16.6ms

  而setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行

  requestAnimationFrame采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果

特点

  【1】requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率

  【2】在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量

  【3】requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销

使用

  requestAnimationFrame的用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行

  1. requestID = requestAnimationFrame(callback);
  1. //控制台输出1和0
  2. var timer = requestAnimationFrame(function(){
  3. console.log(0);
  4. });
  5. console.log(timer);//

  cancelAnimationFrame方法用于取消定时器

  1. //控制台什么都不输出
  2. var timer = requestAnimationFrame(function(){
  3. console.log(0);
  4. });
  5. cancelAnimationFrame(timer);

  也可以直接使用返回值进行取消

  1. var timer = requestAnimationFrame(function(){
  2. console.log(0);
  3. });
  4. cancelAnimationFrame(1);

兼容

  IE9-浏览器不支持该方法,可以使用setTimeout来兼容

  1. if(!window.requestAnimationFrame){
  2. var lastTime = 0;
  3. window.requestAnimationFrame = function(callback){
  4. var currTime = new Date().getTime();
  5. var timeToCall = Math.max(0,16.7-(currTime - lastTime));
  6. var id = window.setTimeout(function(){
  7. callback(currTime + timeToCall);
  8. },timeToCall);
  9. lastTime = currTime + timeToCall;
  10. return id;
  11. }
  12. }
  1. if (!window.cancelAnimationFrame) {
  2. window.cancelAnimationFrame = function(id) {
  3. clearTimeout(id);
  4. };
  5. }

应用

  现在分别使用setInterval、setTimeout和requestAnimationFrame这三个方法制作一个简单的进制度效果

【1】setInterval

  1. <div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
  2. <button id="btn">run</button>
  3. <script>
  4. var timer;
  5. btn.onclick = function(){
  6. clearInterval(timer);
  7. myDiv.style.width = '0';
  8. timer = setInterval(function(){
  9. if(parseInt(myDiv.style.width) < 500){
  10. myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
  11. myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
  12. }else{
  13. clearInterval(timer);
  14. }
  15. },16);
  16. }
  17. </script>

【2】setTimeout

  1. <div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
  2. <button id="btn">run</button>
  3. <script>
  4. var timer;
  5. btn.onclick = function(){
  6. clearTimeout(timer);
  7. myDiv.style.width = '0';
  8. timer = setTimeout(function fn(){
  9. if(parseInt(myDiv.style.width) < 500){
  10. myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
  11. myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
  12. timer = setTimeout(fn,16);
  13. }else{
  14. clearTimeout(timer);
  15. }
  16. },16);
  17. }
  18. </script>

【3】requestAnimationFrame

  1. <div id="myDiv" style="background-color: lightblue;width: 0;height: 20px;line-height: 20px;">0%</div>
  2. <button id="btn">run</button>
  3. <script>
  4. var timer;
  5. btn.onclick = function(){
  6. myDiv.style.width = '0';
  7. cancelAnimationFrame(timer);
  8. timer = requestAnimationFrame(function fn(){
  9. if(parseInt(myDiv.style.width) < 500){
  10. myDiv.style.width = parseInt(myDiv.style.width) + 5 + 'px';
  11. myDiv.innerHTML = parseInt(myDiv.style.width)/5 + '%';
  12. timer = requestAnimationFrame(fn);
  13. }else{
  14. cancelAnimationFrame(timer);
  15. }
  16. });
  17. }
  18. </script>
 
 
 
 
 
 
 
 
 
 
 

深入理解定时器系列——被誉为神器的requestAnimationFrame的更多相关文章

  1. 深入理解定时器系列第二篇——被誉为神器的requestAnimationFrame

    × 目录 [1]引入 [2]特点 [3]使用[4]兼容[5]应用 前面的话 与setTimeout和setInterval不同,requestAnimationFrame不需要设置时间间隔.这有什么好 ...

  2. 深入理解定时器系列第一篇——理解setTimeout和setInterval

    × 目录 [1]setTimeout [2]setInterval [3]运行机制[4]作用[5]应用 前面的话 很长时间以来,定时器一直是javascript动画的核心技术.但是,关于定时器,人们通 ...

  3. 深入理解JavaScript系列(结局篇)

    介绍 最近几个月忙得实在是不可开交,终于把<深入理解JavaScript系列>的最后两篇“补全”了,所谓的全是不准确的,因为很多内容都没有写呢,比如高性能.Ajax安全.DOM详解.Jav ...

  4. 深入理解javascript系列(4):立即调用的函数表达式

    本文来自汤姆大叔 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法 ...

  5. 深入理解javascript系列,读书笔记

    深入理解JavaScript系列(2):揭秘命名函数表达式 1.讲了函数声明和函数表达式的区别,包括一些在函数提升上的区别 2.如果给函数表达式的函数也取名,会在调试的时候受益 3.不要在block( ...

  6. 深入理解JavaScript系列

    转自http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 深入理解JavaScript系列(1):编写高质量JavaScript代码 ...

  7. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...

  8. [JS]深入理解JavaScript系列(4):立即调用的函数表达式

    转自:汤姆大叔的博客 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.在详细了解这个之前,我们来谈了解一下"自执行"这个叫法 ...

  9. 深入理解JavaScript系列(转自汤姆大叔)

    深入理解JavaScript系列文章,包括了原创,翻译,转载,整理等各类型文章,如果对你有用,请推荐支持一把,给大叔写作的动力. 深入理解JavaScript系列(1):编写高质量JavaScript ...

随机推荐

  1. 关于JS事件的几点总结

    1.理解事件(2点) 事件行为本身:没有给事件绑定方法事件也是一直存在的,当触发行为的时候,也对触发对应的行为,只不过由于没有绑定事件,导致没有任何事件发生: 事件绑定:给元素绑定一个方法:触发行为, ...

  2. docker 初探之简单安装 ----Windows10

    报错一 $ docker run hello-world Unable to find image 'hello-world:latest' locally Pulling repository do ...

  3. optparse

    Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...

  4. Activity系列讲解---三大基本状态与七大生命周期函数

    简介:四大组件之一,在应用中一个Activity可以用来表示一个界面,可以理解为用户可视化界面,一个android应用必须通过Activity来运行和启动. 1.三大基本状态与七大生命周期函数 2.代 ...

  5. java大并发数据保存方案

    做了几年.net,如今终于要做java了. 需求: 线下终端会定时上传gps位置到服务端,服务端收到数据保存到mysql数据库,当线下终端过多时,问题出现了,首当其冲的是数据库连接池经常会崩溃,单个t ...

  6. 基于log4net的帮助类Log

    using log4net; using System; using System.Collections.Generic; using System.Diagnostics; using Syste ...

  7. selenium测试框架篇,页面对象和元素对象的管理

    前期已经做好使用Jenkins做buildhttp://www.cnblogs.com/tobecrazy/p/4529399.html 做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让 ...

  8. 简化MSI在WIN10的安装

    这里给大家分享一个简化MSI安装的工具 InstallByDrag: 在win10系统中,通过双击方式打开 MSI 安装文件,可能被提示由于dll加载问题无法安装,这是由于没有使用管理员权限运行.而M ...

  9. Python3.5之TuShare

    这部分是直接搬运过来的,官方网站http://tushare.waditu.com/ TuShare是一个免费.开源的python财经数据接口包.主要实现对股票等金融数据从数据采集.清洗加工 到 数据 ...

  10. XML 基础

    linux下xml编辑器 vim gedit editix wonderful;免费30天;可以进行有效性检查 xerces oxygen 收费 xmlcopyedit serna free 是ser ...