[js高手之路] html5新增的定时器requestAnimationFrame实战进度条
在requestAnimationFrame出现之前,我们一般都用setTimeout和setInterval,那么html5为什么新增一个requestAnimationFrame,他的出现是为了解决什么问题?
优势与特点:
1)requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
2)在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
3)requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销
一句话就是:这玩意性能高,不会卡屏,根据不同的浏览器自动调整帧率。如果看不懂或者不理解,也没有什么关系,这玩意跟浏览器渲染原理有关。我们先学会使用它!
如何使用requestAnimationFrame?
使用方式跟定时器setTimeout差不多,不同之处在于,他不需要设置时间间隔参数
var timer = requestAnimationFrame( function(){
console.log( '定时器代码' );
} );
参数是一个回调函数,返回值是一个整数,用来表示定时器的编号.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var aInput = document.querySelectorAll( "input" ),
timer = null;
aInput[0].onclick = function(){
timer = requestAnimationFrame( function say(){
console.log( 1 );
timer = requestAnimationFrame( say );
} );
};
aInput[1].onclick = function(){
cancelAnimationFrame( timer );
}
}
</script>
</head>
<body>
<input type="button" value="开启">
<input type="button" value="关闭">
</body>
</html>
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
如果浏览器都不认识AnimationFrame,就用setTimeout兼容.
运用3种不同的定时器(setTimeout, setInterval, requestAnimationFrame)实现一个进度条的加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width:0px;
height:40px;
border-radius:20px;
background:#09f;
text-align:center;
font:bold 30px/40px '微软雅黑';
color:white;
}
</style>
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
clearInterval( timer );
oBox.style.width = '0';
timer = setInterval( function(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
}else {
clearInterval( timer );
}
}, 1000 / 60 );
}
}
</script>
</head>
<body>
<div>0%</div>
<p><input type="button" value="ready!Go"></p>
</body>
</html>

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width:0px;
height:40px;
border-radius:20px;
background:#09f;
text-align:center;
font:bold 30px/40px '微软雅黑';
color:white;
}
</style>
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
clearInterval( timer );
oBox.style.width = '0';
timer = setInterval( function(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
}else {
clearInterval( timer );
}
}, 1000 / 60 );
}
}
</script>
</head>
<body>
<div>0%</div>
<p><input type="button" value="ready!Go"></p>
</body>
</html>
run code
二、setTimeout方式
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
clearTimeout( timer );
oBox.style.width = '0';
timer = setTimeout( function go(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
timer = setTimeout( go, 1000 / 60 );
}else {
clearInterval( timer );
}
}, 1000 / 60 );
}
}
</script>
三、requestAnimationFrame方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width:0px;
height:40px;
border-radius:20px;
background:#09f;
text-align:center;
font:bold 30px/40px '微软雅黑';
color:white;
}
</style>
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
cancelAnimationFrame( timer );
oBox.style.width = '0';
timer = requestAnimationFrame( function go(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
timer = requestAnimationFrame( go );
}else {
cancelAnimationFrame( timer );
}
} );
}
}
</script>
</head>
<body>
<div>0%</div>
<p><input type="button" value="ready!Go"></p>
</body>
</html>
[js高手之路] html5新增的定时器requestAnimationFrame实战进度条的更多相关文章
- [js高手之路] html5 canvas动画教程 - 实时获取鼠标的当前坐标
有了前面的canvas基础之后,现在开始就精彩了,后面写的canvas教程都是属于综合应用,前面已经写了常用的canvas基础知识,参考链接如下: [js高手之路] html5 canvas系列教程 ...
- [js高手之路]html5 canvas动画教程 - 下雪效果
利用canvas,实现一个下雪的效果,我们先预览下效果: 我们先分析下这个效果: 1,随机产生雪花 2,雪花的产生不是同时产生,而是有先后顺序的 3,雪花怎么表示 4,怎么源源不断的下雪 5,雪花有大 ...
- [js高手之路] html5 canvas系列教程 - 掌握画直线图形的常用API
我们接着上文[js高手之路] html5 canvase系列教程 - 认识canvas以及基本使用方法继续. 一.直线的绘制 cxt.moveTo( x1, y1 ): 将画笔移动到x1, y1这个点 ...
- [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)
之前,我写了一个arc函数的用法:[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形). arcTo: cxt.arcTo( cx, cy, x2, y2, ...
- [js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形)
绘制曲线,经常会用到路径的知识,如果你对路径有疑问,可以参考我的这篇文章[js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解. arc:画 ...
- [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)
接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...
- [js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)
接着上文线条样式[js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)继续. canvas提供两种输出文本的方 ...
- [js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)
上文,写完弧度与贝塞尔曲线[js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具),本文主要是关于线条的样式设置 lineWidth: 设置线条的宽 ...
- [js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)
接着上文[js高手之路] html5 canvas系列教程 - 状态详解(save与restore),相信大家都应该玩过美颜功能,而我们今天要讲的就是canvas强大的像素处理能力,通过像素处理,实现 ...
随机推荐
- 扩展Python模块系列(四)----引用计数问题的处理
承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...
- jQuery遍历-过滤
缩写搜索元素的范围 三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素. 其他过滤方法,比如 filter() 和 not() ...
- python基础教程(十)
魔法方法.属性 ------------------------ 准备工作 为了确保类是新型类,应该把 _metaclass_=type 入到你的模块的最开始. class NewType(Objec ...
- JDBCTemplate
1.Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装.语法风格非常接近DBUtils. JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTem ...
- SVG文本
前面的话 本文将详细介绍SVG文本相关内容 位置属性 在一个SVG文档中,使用<text>元素来设置文本,<text>元素有x.y.dx.dy这四个位置属性 [x和y] 属性x ...
- C++基础:二维数组动态的申请内存和释放内存
使用二维数组的时候,有时候事先并不知道数组的大小,因此就需要动态的申请内存.常见的申请内存的方法有两种:malloc/free 和 new/delete. 一.malloc/free (1)申请一维数 ...
- linux下操作mysql
有关mysql数据库方面的操作,必须首先登录到mysql中. 开启MySQL服务后,使用MySQL命令可以登录.一般使用mysql -uroot -p即可.如果数据库不是本机,则需要加参数,常用参数如 ...
- spring mvc:@RequestParam与@ModelAttribute异同
关于spring mvc中的两个注解:@RequestParam.@ModelAttribute区别,原先并没有特别注意,直到最近找别人开发的一个小模块的bug时,才有意识的比较了两者的区别. 1.@ ...
- Maven(二)Maven项目的创建(命令、myeclipse)及生命周期
上一篇给大家介绍了Maven的概念和仓库的一些信息,接下来给大家分享一下使用命令和MyEclipse创建Maven项目 一.使用命令管理Maven项目 1.1.创建Maven java项目 1)创建一 ...
- 规则集Set与线性表List性能分析
前言 本章节将通过实验,测试规则集与线性表的性能.那么如何进行实验呢?针对不同的集合都进行指定数量元素的添加和删除操作,计算耗费时间进行分析. 那么,前两个章节呢,我们分别讲述了什么时候使用Set以及 ...