window.requestAnimationFrame讲解
为什么要说它,源于看到的一道面试题:问题是用js实现一个无限循环的动画。
首先想到的是定时器
<!doctype html>
<html lang="en">
<head><title>Document</title><style>#e{width: 100px;height: 100px;background: red;position: absolute;left: 0;top: 0;zoom: 1;}</style>
</head>
<body>
<div id="e"></div>
<script>var e = document.getElementById("e");var flag = true;var left = 0;function render() {if(flag == true){if(left>=100){flag = false}e.style.left = ` ${left++}px`}else{if(left<=0){flag = true}e.style.left = ` ${left--}px`}}setInterval(function(){render()},1000/60)</script>
</body>
</html>
可以说是完美实现!
至于时间间隔为什么是1000/60,这是因为大多数屏幕渲染的时间间隔是每秒60帧。
既然setInterval可以搞定为啥还要用requestAnimationFrame呢?
不同之处在于,setInterval必须指定多长时间再执行,window.requestAnimationFrame()则是推迟到浏览器下一次重绘时就执行回调。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,requestAnimationFrame()会暂停执行。
如果某个函数会改变网页的布局,一般就放在window.requestAnimationFrame()里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。
直接上代码:
注意: requestAnimationFrame()在浏览器重绘前执行,所以要想执行requestAnimationFrame()必须要让浏览器触发重绘。
<!doctype html>
<html lang="en">
<head><title>Document</title><style>#e{width: 100px;height: 100px;background: red;position: absolute;left: 0;top: 0;zoom: 1;}</style>
</head>
<body>
<div id="e"></div>
<script>var e = document.getElementById("e");var flag = true;var left = 0;function render() {if(flag == true){if(left>=100){flag = false}e.style.left = ` ${left++}px`}else{if(left<=0){flag = true}e.style.left = ` ${left--}px`}}//requestAnimationFrame效果(function animloop() {render();window.requestAnimationFrame(animloop);})();</script>
</body>
</html>
但是,怎么停止requestAnimationFrame?是否有类似clearInterval这样的类似方法?
答案是确定的。requestAnimationFrame()返回一个 long 整数,请求 ID ,是回调列表中唯一的标识,是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
<!doctype html>
<html lang="en">
<head><title>Document</title><style>#e{width: 100px;height: 100px;background: red;position: absolute;left: 0;top: 0;zoom: 1;}</style>
</head>
<body>
<div id="e"></div>
<script>var e = document.getElementById("e");var flag = true;var left = 0;var rafId = nullfunction render() {if(flag == true){if(left>=100){flag = false}e.style.left = ` ${left++}px`}else{if(left<=0){flag = true}e.style.left = ` ${left--}px`}}//requestAnimationFrame效果(function animloop(time) {console.log(time,Date.now())render();rafId = requestAnimationFrame(animloop);//如果left等于50 停止动画if(left == 50){cancelAnimationFrame(rafId)}})();//setInterval效果// setInterval(function(){// render()// },1000/60)</script>
</body>
</html>
MDN链接
总结:
function animloop() {console.log('aa')}window.requestAnimationFrame(animloop);
浏览器其实一直在刷新,当给window.requestAnimationFrame传入一个回调函数的时候,那么就是告诉浏览器在渲染前执行一下这个回调函数。
(function animloop(time) {console.log('time', Date.now())rafId = requestAnimationFrame(animloop);})();
或者
<script>let i= 0;function clock() {console.log(i)window.requestAnimationFrame(clock);}window.requestAnimationFrame(clock);
</script>
上面这段代码只要一执行,那么就会停不下来。
原因是:我们可以把requestAnimationFrame想象成setTimeout,由于requestAnimationFrame并不是在所有的浏览器中都支持,那么我们可以写一个用setTimeout实现的polyfill,而setTimeout又是异步的,所以,进入异步队列后又调用那个回调,这样一直回调下去,所以能够一直执行。
如下:
// 这段代码不全
if (!window.requestAnimationFrame) {window.requestAnimationFrame = function(callback, element) {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;};
}
window.requestAnimationFrame讲解相关推荐
- window.requestAnimationFrame
今天小猪在看一个html5的demo时一直在找他的动画是怎么实现的,按照我的理解就应该是调用setInterval来循环调用动画函数来实现.但是在Demo中就是找不到这个函数.干着急的小猪只好一步一步 ...
- 网页性能管理详解:浅谈chrome-Timeline及window.requestAnimationFrame()方法
你遇到过性能很差的网页吗? 这种网页响应非常缓慢,占用大量的CPU和内存,浏览起来常常有卡顿,页面的动画效果也不流畅. 你会有什么反应?我猜想,大多数用户会关闭这个页面,改为访问其他网站.作为一个开发 ...
- window.requestAnimationFrame Web3D渲染帧率控制
目录 window.requestAnimationFrame简介 定义 语法 参数 返回值 使用注意 两种方式控制帧率 默认帧数中取适当次数更新 用延时控制帧率更新的频率 总结 注意: window ...
- window.requestAnimationFrame强大的前端动画神器
今天介绍一个功能强大的api-window.requestAnimationFrame,它既可以实现如丝般顺滑的动画,又能充当性能优化的利器,还能代替setTimeout,setInterval等定时 ...
- 浏览器动画window.requestAnimationFrame
新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 再看别人现实粒子效果的时候会有以下码代: 1 window.requestAnimationFrame || (window.req ...
- 数字滚动原生js的三种方式
数字滚动原生js的三种方式 让数字滚动的效果简单用计时器setInterval就能轻易的实现,例如 <!DOCTYPE html> <html><head>< ...
- JS 动画基础: 细说 requestAnimationFrame
JS 动画基础: 细说 requestAnimationFrame 文章目录 JS 动画基础: 细说 requestAnimationFrame 简介 参考 完整示例代码 正文 `setInterva ...
- js动画requestAnimationFrame详解
看这篇文章之前我希望你会用setTimeout做简单的动画,也就是利用递归来代替setInterval做动画. requestAnimationFrame() 他的作用就是代替定时器做更加流畅高性能的 ...
- requestAnimationFrame,Web中写动画的另一种选择
HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了: 你可以用CSS3的animattion+keyframes; 你也可以用css3的transition; 你还可以用通过在canv ...
- 动画requestAnimationFrame
前言 在研究canvas的2D pixi.js库的时候,其动画的刷新都用requestAnimationFrame替代了setTimeout 或 setInterval 但是jQuery中还是采用了s ...
最新文章
- 一文读懂神经网络初始化!吴恩达Deeplearning.ai最新干货
- ARM平台下独占访问指令LDREX和STREX的原理与使用详解
- linux内核启动时间优化
- mysql学习笔记12 其他函数
- CMU本科计算机科学,CMU计算机科学学院本科难录吗?
- html字符串变量,字符串变量中的Python HTML
- SAP License:SAP系统中的删除命令
- 基于swing的java系统_Java实验--基于Swing的简单的歌曲信息管理系统(一)
- laravel下载安装
- Oracle数据库练习题及答案(个人总结)
- 深圳率先立法:支持L3自动驾驶上路,凡公开道路皆可行
- 【OpenCV笔记】光流法之金字塔Lucas-Kanade
- 当年“你说什么,我都能实现”的软件公司,后来都是怎么死的?
- 【杂谈】嵌入式软件数据结构的特点
- 如何缓解自己紧张焦虑的情绪?
- 中文拼音首字母排序比较器
- js图片切换 幻灯片效果
- js创建节点及节点操作
- 数组(一维数组与二维数组)
- nohup 命令简介