Lambda博客
  • 自我介绍
  • SSR
    • 浅谈SSR
  • React
    • 页面路由——React-Router
    • 管好你的状态——React-Redux
    • 一个哪行——React详解
    • 左膀右臂一个不少——React初探
  • 问题记录
    • js-xlsx实现纯前端导出excel表格
    • 前端开发需要了解的东西
    • 打造高性能网站
  • JavaScript学习笔记
    • 语法和API
    • js-垃圾回收
    • 收集的JS使用技巧
    • 执行机制
    • 原型和原型链
    • 执行上下文
    • 事件循环
    • JavaScript手写代码
    • 43道JS面试题
    • 悄悄的带走了你的东西——闭包详解
    • 你是个富二代吗?——JavaScript作用域链
    • 捉摸不透的女生——JavaScript类型转换
    • 这是你的女神!——JavaScript
  • 网络学习笔记
    • 强不强——HTTP-协商缓存VS强缓存
    • 网络缓存
    • 我要飞的更高——计算机网络
    • 快点!再快点!——CDN
    • 喜怒哀乐多状态——HTTP状态码
    • 你会爱上我的(ಥ_ಥ) ——TCP详解
    • 隔壁老王想篡位?门都没有——同源策略
  • 软技能
  • 安全专题
    • 保护好自己——网站安全,预防
  • 浏览器兼容性
    • 我是个好人——浏览器兼容性
  • 多图片加载——懒加载详解
  • 数据结构
  • Node
    • Node初探
  • Typescript
    • JS Plus 真香——初探 TypeScript
  • 设计模式
    • 不要花里胡哨,要一套一套——设计模式(1)
    • 学会“套路”——设计模式(2)
  • Vue
    • 实操实干——vue实例记录
    • 停下来,问问自己——Vue-刨根问底
    • 你有喘息的机会吗?——Vue,逐步了解
    • 你累吗?来来来,安利框架——Vue-初次见面
  • 小程序
    • 今天天气怎么样——记一次小程序开发
  • Webpack
    • 蛋糕分割整合工具——Webpack-前端工程化
  • 你一块,我一块——Web-modules 前端模块化
  • HTML5
    • 你会画小猪佩奇吗?—— canvas
    • 画个矢量图——HTML5-SVG
    • 听说你爱闹腾——HTML5-多媒体
    • 动画神器——HTML5-requestAnimationFrame
    • 留下痕迹——HTML5-客户端存储
    • 你知道指北针吗?——HTML5-DeviceMotionEvent
    • 你在哪啊?我在这啊——HTML5-Geolocation
    • 你到这,你到那——HTML5-拖拽
    • 你从这,到那——HTML5-拖拽上传文件
    • 开启前端之路——HTML 标签
  • 瀑布流(无限滚动)
  • 我是怎么来的?——浏览器渲染原理
  • Css
    • 由大变小,你行吗 —— 移动端
    • 动起来,这样比较炫—— CSS3 动画
    • 请不要拐弯抹角 —— CSS3 选择器
    • 想炫吗?—— CSS3 属性
    • 最后的最后——CSS自问自答
    • 万事开头难?——深入学习前端常见布局
    • 一入前端深似海——BFC剖析
    • 还有哪些好玩的东西——CSS提升
    • 那些好看的页面是怎么形成的——CSS 初识
  • 拿个小本本记下——Cookie
由 GitBook 提供支持
在本页
  • 屏幕绘制频率
  • 原理
  • 兼容
在GitHub上编辑
  1. HTML5

动画神器——HTML5-requestAnimationFrame

上一页听说你爱闹腾——HTML5-多媒体下一页留下痕迹——HTML5-客户端存储

最后更新于3年前

在 Web 应用中,实现动画效果的方法比较多,JavaScript 中可以通过定时器 setTimeout 来实现,Css3 可以使用 transition 和 animation 来实现,HTML5 中的 canvas 也可以实现。除此之外,HTML5 还提供了一个专门用于请求动画的 API,即 requestAnimationFrame(rAF) 顾名思义就是请求动画帧。

屏幕绘制频率

屏幕绘制频率即图像在屏幕上更新的速度,也是屏幕上图像每秒钟出现的次数,它的单位是赫兹(HZ),对于一般的笔记本电脑,这个频率大概是60HZ。因此,当你对着电脑屏幕什么也不做的情况下,显示器也会以以每秒60次的频率在不断地更新屏幕上的图像,那么我们为什么感觉不到这个变化呢?那是因为人的眼睛有 即前一刻画面留在大脑印象还没消失,紧接着后幅画面就跟上来了,这中间只隔了16.7ms(1000/60≈16.7),所以会让你误以为屏幕上的图像是静止不动的。

原理

window.requestAnimationFrame()告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个毁掉函数作为参数,该回调函数会在浏览器下次重绘之前执行。

该函数有返回值,建议使用一个ID进行标识,没有别的意义,可以传给window.cancelAnimationFrame()取消回调函数

总结

  1. 页面刷新前执行一次

  2. 1000ms 60fps -> 16ms

  3. cancelAnimationFrame 用来取消

  4. 用法和 setTimeout 类似

  5. 兼容性查看

若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()

兼容

对于不同的浏览器,requestAnimationFrame 这个api的名字也略有差异,针对低版本浏览器,这里写出对应的兼容性写法封装。

// requestAnimationFrame 的封装
/**
 * 针对不同内核的浏览器的API写法不同进行兼容
 */
window.requestAnimaFrame = (function(){
  return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function (callback) {
          window.setTimeout(callback, 1000 / 60)
        }
})();
// cancelAnimationFrame
/**
 * 针对不同内核的浏览器的API写法不同进行兼容
 */
window.cancelAnimFrame = (function(){
  return window.cancelAnimationFrame ||
        window.webkitCancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        function (id) {
          window.clearTimeout(id)
        }
})

代码示例

<div id="a" style="width: 100px; 
            height: 100px;
            background-color: red;
            position: absolute;"
            >
</div>

<script>
/**
 * 定义一个div盒子,动画设置向右平移 500px
 * 
 * 注:这里使用的requestAnimaFrame和cancelAnimFrame方法名为自己封装的方法
 */
let start = 0,
    end = 500,
    ele = document.querySelector('#a'),
    req;
let f = function () {
  start += 10
  ele.style.left = start + 'px'
  // 距离页面左边的距离
  let left = ele.getBoundingClientRect().left
  if(left < end) {
    req = requestAnimaFrame(f)
  } else {
    cancelAnimFrame(req)
  }
}
</script>
nF8UJS.gi
视觉停留效应
caniuse