的黑魔法,js高手之路

set提姆eout 的黑魔法

2016/05/03 · JavaScript
· 1 评论 ·
settimeout

原文出处:
李三思   

set提姆eout,前端工程师必定会打交道的一个函数.它看起来特其他概括,朴实.有着一个很不经常的名字–定时器.让年少的本人天真的以为自己可以操纵未来.却不知朴实之中隐含着惊天大密.我还记得自己首回用这么些函数的时候,我天真的觉得它就是js完成八线程的工具.当时用它完结了一个坦克大战的小游戏,玩儿不亦新浪.可是随着在前端那条路上越走越远,对它明白起来发生了变化.它犹如开始蒙上了面纱,时常有一对竟然的变现让自家捉摸不透.终于,我的耐心耗尽,下定狠心,要摘除它的面具,一钻探竟.

要说set提姆eout的本源,就得从它的法定概念说起.w3c是这么定义的

set提姆eout() 方法用于在指定的飞秒数后调用函数或计算表达式。

见状如此一个证实,大家领悟了它就是一个定时器,大家设定的函数就是一个”闹钟”,时间到了它就会去执行.但是聪慧的您忍不住有这样一个难题,假使是settimeout(fn,0)呢?根据定义的印证,它是还是不是会立即执行?实践是印证真理的唯一标准,让大家来看望上边的尝试

JavaScript

<!DOCTYPE html> <html lang=”en”> <head> <meta
charset=”UTF-8″> <title></title> </head>
<body> <script> alert(1); setTimeout(“alert(2)”, 0);
alert(3); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    
    <script>
        alert(1);
        setTimeout("alert(2)", 0);
        alert(3);
    </script>
</body>
</html>

那是一个很粗略的试验,假使settimeout(0)会立时施行,那么这里的实施结果就相应是1->2>3 
. 但是实际上的结果却是1->3->2.
这讲明了settimeout(0)并不是即时执行.同时让咱们对settimeout的行为感到很诡异.

在requestAnimationFrame出现此前,大家一般都用set提姆eout和setInterval,那么html5为何新增一个requestAnimationFrame,他的出现是为着解决哪些难点?

在requestAnimationFrame出现往日,大家一般都用set提姆eout和setInterval,那么html5为何新增一个requestAnimationFrame,他的出现是为了化解哪些难点?

Javascript定时器(一)——单线程

一、JavaScript 引擎是单线程的

 

可以从下面的代码中见到,第二个用set提姆eout中的代码是死循环,由于是单线程,上边的五个定时器就没机会执行了。

 

<script type=”text/javascript”>

    setTimeout( function(){ while(true){} } , 100); 

    setTimeout( function(){ alert(‘你好!setTimeout’); } , 200); 

    setInterval( function(){ alert(‘你好!setInterval’); }  , 200); 

</script>

浏览器的基业是三十二线程的,它们在基本制控下相互合作以保持同步,一个浏览器至少落成3个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

 

JavaScript引擎是基于事件驱动单线程执行的,JS引擎一贯等待着义务队列中职责的赶到然后加以处理,浏览器无论再如何时候都唯有一个JS线程在运转JS程序。

GUI渲染线程负责渲染浏览器界面,当界面必要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会履行。但必要小心
GUI渲染线程与JS引擎是排斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被封存在一个队列中等到JS引擎空闲时立时被实践。

浏览器事件触发线程,当一个轩然大波被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这一个事件可来自JavaScript引擎当前执行的代码块如set提姆eOut、也可来自浏览器内核的别样线程如鼠标点击、AJAX异步请求等,但鉴于JS的单线程关系有着这几个事件都得排队等候JS引擎处理。

 

 

  由上图可观望,浏览器中的JavaScript引擎是按照事件驱动的,那里的事件可看成是浏览器派给它的种种任务,JavaScript引擎一直等候着职责队列中义务的来临,由于单线程关系,这个职分得进行排队,一个随着一个被引擎处理。

 

t1、t2….tn意味分裂的时间点,tn上边对应的小方块代表该时间点的天职。

 

t1时刻:

的黑魔法,js高手之路。 

GUI渲染线程

浏览器事件触发线程:

在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可以,对于JavaScript引擎线程来说,那事件是由其余线程异步传到职责队列尾的,由于发动机正在处理t1时的职责,那么些鼠标点击事件正在等待处理。

定时触发线程:

此地的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,假若处在阻塞线程状态就计不了时,它必须看重外部来计时并触发定时,所以队列中的定时事件是异步事件。

在这t1的时间段内,继鼠标点击事件触发后,先前已设置的set提姆eout定时也抵达了,此刻对JavaScript引擎来说,定时触发线程发生了一个异步定时事件并放置职分队列中,该事件被排到点击事件回调之后,等待处理。同理,仍然在t1时间段内,接下去某个setInterval定时器也被添加了,由于是距离定时,在t1段内一连被触发了四次,那八个事件被排到队尾等待处理。

ajax异步请求:

浏览器新开一个http线程请求,当呼吁的情景变更时,如若原先已设置回调,那异步线程就发出状态变更事件放到JavaScript引擎的拍卖队列中等候处理。

二、职分的进行顺序分化,显示结果也不比

 

1)未使用setTimeout函数

 

在网上找到的一段代码实例,那里用来演示一下。

 

复制代码

<a href=”#亚洲必赢官网,” id=”doBtn”>do something</a>

<div id=”status”></div>

<script type=”text/javascript”>

      var doBtn = document.getElementById(‘doBtn’)

          , status = document.getElementById(‘status’);

 

      function sleep(ms) {

        var start = new Date();

        while (new Date() – start <= ms) {}

      }

      

      doBtn.onclick = function(e) {

          status.innerHTML = ‘doing…please wait…’;  

          sleep(3000);  // 模拟一个耗时较长的臆度进程,3s

          status.innerHTML = ‘done’;  

          return false;

      };

</script>

复制代码

我在firefox中实践了上边的代码。安排是点击“do
something”按钮,然后呈现“doing…please
wait…”,接着执行sleep,最终呈现“done”。

 

不过结果是点击后,浏览器卡住3秒左右,最终直接显示done。

 

解析下看看,在做status.innerHTML设置的时候,是要求进行GUI渲染线程的,不过现在还在实践JavaScript引擎线程,而JavaScript引擎线程与GUI渲染线程是排斥的,所以就最终展现了done。

 

 

 

2)使用了setTimeout函数

 

复制代码

<a href=”#” id=”doBtn2″>do something timer</a>

<div id=”status2″></div>

<script type=”text/javascript”>

      var doBtn2 = document.getElementById(‘doBtn2’)

          , status2 = document.getElementById(‘status2’);

 

      function sleep2(ms) {

        var start = new Date();

        while (new Date() – start <= ms) {}

      }

      

      doBtn2.onclick = function(e) {

          status2.innerHTML = ‘doing…please wait…’; 

          setTimeout(function() {

            sleep2(3000); 

            status2.innerHTML = ‘done’; 

          }, 100); 

          return false;

      };

</script>

复制代码

在“doing…please
wait…”前面加了个set提姆eout,延时执行,给了浏览器渲染的时日,那个时候会体现出“doing…please
wait…”的字样,然后实施sleep函数,最后突显“done”。

 

 

 

背后有网友发现在firefox中不起效率,的确有这几个标题,后面我修改了一下代码,将一些变量的宣示,onclick的绑定放到了window.onload事件中,等页面结构加载成功后,我再做脚本操作。

 

复制代码

<script type=”text/javascript”>

      function sleep(ms) {

        //…

      }

      window.onload = function() {

            var doBtn = document.getElementById(‘doBtn’),

            status = document.getElementById(‘status’);

            

            var doBtn2 = document.getElementById(‘doBtn2’)

              , status2 = document.getElementById(‘status2’);

              

            doBtn.onclick = function(e) {

                //…

            };

            doBtn2.onclick = function(e) {

                //…

            };

      };

</script>

一、JavaScript
引擎是单线程的
能够从下面的代码中来看,第二个用set提姆eout中的代码是死循环,由于是单线程…

js引擎是单线程执行的

大家先把地点的标题放一放.从js语言的规划上来探视是否能找到马迹蛛丝.

大家发现js语言设计的一个很重大的点是,js是绝非三十二线程的.js引擎的施行是单线程执行.这些特点曾经困扰自己很久,我想不清楚既然js是单线程的,那么是何人来为定时器计时的?是何人来发送ajax请求的?我陷入了一个盲区.即将js等同于浏览器.我们习惯了在浏览器里面实践代码,却不经意了浏览器本身.js引擎是单线程的,不过浏览器却可以是三十二线程的,js引擎只是浏览器的一个线程而已.定时器计时,网络请求,浏览器渲染等等.都是由分歧的线程去做到的.
口说无凭,我们依旧看一个例子

JavaScript

<!DOCTYPE html> <html lang=”en”> <head> <meta
charset=”UTF-8″> <title></title> </head>
<body> </body> <script> var isEnd = true;
window.setTimeout(function () { isEnd = false;//1s后,改变isEnd的值 },
1000); while (isEnd); alert(‘end’); </script> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    
</body>
<script>
    var isEnd = true;
    window.setTimeout(function () {
        isEnd = false;//1s后,改变isEnd的值
    }, 1000);
    while (isEnd);
    alert(‘end’);
</script>
</html>

isEnd默许是true的,在while中是死循环的.最终的alert是不会履行的.
我添加了一个定时器,1秒后将isEnd改为false.
假如说js引擎是三四线程的,那么在1秒后,alert就会被执行.但是实际上情状是,页面会永远死循环下去.alert并从未执行.那很好的求证了,settimeout并不可以同日而语八线程使用.js引擎执行是单线程的.

优势与特性:

优势与特征:

event loop

从上边的实验中,大家更是困惑了,settimeout到底做了什么工作吗?

原先照旧得从js语言的规划上追寻答案.

亚洲必赢官网 1

js引擎单线程执行的,它是按照事件驱动的语言.它的履行各类是依照一个名为事件队列的机制.从图中大家可以看看,浏览器有多种多样的线程,比如事件触发器,网络请求,定时器等等.线程的牵连都是根据事件的.js引擎处理到与其他线程相关的代码,就会散发给此外线程,他们处理完事后,必要js引擎计算时就是在事件队列里面添加一个义务.
那么些历程中,js并不会阻塞代码等待其余线程执行达成,而且其余线程执行完结后添加事件义务告诉js引擎执行有关操作.那就是js的异步编程模型.

那般我们再回过头来看settimeout(0)就会冷不丁大悟.js代码执行到那里时,会张开一个定时器线程,然后继续执行下边的代码.该线程会在指定时间后往事件队列里面插入一个任务.由此可见settimeout(0)里面的操作会放在所有主线程任务之后.
那也就表明了干吗第二个试验结果是1->3-2 .

由此可知官方对于settimeout的定义是有迷惑性的.应该给一个新的概念:

在指定时间内, 将职分放入事件队列,等待js引擎空闲后被执行.

1)requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一遍重绘或回流中就完成,并且重绘或回流的刻钟间隔牢牢追随浏览器的基础代谢频率

1)requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在四次重绘或回流中就完毕,并且重绘或回流的年华间隔牢牢追随浏览器的刷新频率

js引擎与GUI引擎是排斥的

谈到那里,就只能说浏览器的其它一个引擎—GUI渲染引擎.
在js中渲染操作也是异步的.比如dom操作的代码会在事件队列中生成一个义务,js执行到这些义务时就会去调用GUI引擎渲染.

js语言设定js引擎与GUI引擎是排斥的,也就是说GUI引擎在渲染时会阻塞js引擎总计.原因很粗略,如果在GUI渲染的时候,js改变了dom,那么就会招致渲染分裂步.
大家需求深远通晓js引擎与GUI引擎的关系,因为那与大家一贯开发有关,大家时长会赶上有的很奇葩的渲染难题.看那一个例子

JavaScript

<!DOCTYPE html> <html lang=”en”> <head> <meta
charset=”UTF-8″> <title></title> </head>
<body> <table border=1> <tr><td><button
id=’do’>Do long calc – bad status!</button></td>
<td><div id=’status’>Not Calculating
yet.</div></td> </tr> <tr><td><button
id=’do_ok’>Do long calc – good status!</button></td>
<td><div id=’status_ok’>Not Calculating
yet.</div></td> </tr> </table> <script>
function long_running(status_div) { var result = 0; for (var i = 0; i
< 1000; i++) { for (var j = 0; j < 700; j++) { for (var k = 0; k
< 300; k++) { result = result + i + j + k; } } }
document.querySelector(status_div).innerHTML = ‘calclation done’ ; }
document.querySelector(‘#do’).onclick = function () {
document.querySelector(‘#status’).innerHTML = ‘calculating….’;
long_running(‘#status’); }; document.querySelector(‘#do_ok’).onclick
= function () { document.querySelector(‘#status_ok’).innerHTML =
‘calculating….’; window.setTimeout(function (){
long_running(‘#status_ok’) }, 0); }; </script> </body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <table border=1>
        <tr><td><button id=’do’>Do long calc – bad status!</button></td>
            <td><div id=’status’>Not Calculating yet.</div></td>
        </tr>
        <tr><td><button id=’do_ok’>Do long calc – good status!</button></td>
            <td><div id=’status_ok’>Not Calculating yet.</div></td>
        </tr>
    </table>    
<script>
 
function long_running(status_div) {
 
    var result = 0;
    for (var i = 0; i < 1000; i++) {
        for (var j = 0; j < 700; j++) {
            for (var k = 0; k < 300; k++) {
                result = result + i + j + k;
            }
        }
    }
    document.querySelector(status_div).innerHTML = ‘calclation done’ ;
}
 
document.querySelector(‘#do’).onclick = function () {
    document.querySelector(‘#status’).innerHTML = ‘calculating….’;
    long_running(‘#status’);
};
 
document.querySelector(‘#do_ok’).onclick = function () {
    document.querySelector(‘#status_ok’).innerHTML = ‘calculating….’;
    window.setTimeout(function (){ long_running(‘#status_ok’) }, 0);
};
 
</script>
</body>
</html>

咱俩期待能来看总括的每一个进度,大家在程序起头,计算,甘休时,都实施了一个dom操作,插入了表示当前气象的字符串,Not
Calculating yet.和calculating….和calclation
done.统计中是一个耗时的3重for循环.
在没有应用settimeout的时候,执行结果是由Not Calculating yet
间接跳到了calclation
done.那明显不是大家意在的.而造成如此结果的因由正是js的事件循环单线程机制.dom操作是异步的,for循环统计是一起的.异步操作都会被延缓到一头总结之后执行.也就是代码的实践各类变了.calculating….和calclation
done的dom操作都被放置事件队列后边而且紧跟在联名,造成了丢帧.不能实时的反应.那个事例也告知了我们,在急需实时反馈的操作,如渲染等,和其他连锁联合的代码,要么一起联手,要么一起异步才能确保代码的实践顺序.在js中,就不得不让一起代码也异步.即给for总结增进settimeout.

2)在隐身或不可知的因素中,requestAnimationFrame将不会开展重绘或回流,那自然就意味着更少的CPU、GPU和内存使用量

2)在隐身或不可见的因素中,requestAnimationFrame将不会进行重绘或回流,那自然就象征更少的CPU、GPU和内存使用量

settimeout(0)的作用

差异浏览器的贯彻情形各异,HTML5概念的蝇头时间间隔是4阿秒.
使用settimeout(0)会利用浏览器帮忙的微乎其微时间间隔.所以当大家须求把一部分操作放到下一帧处理的时候,我们经常选取settimeout(0)来hack.

3)requestAnimationFrame是由浏览器专门为卡通提供的API,在运作时浏览器会自行优化措施的调用,并且只要页面不是激活状态下的话,动画会自动刹车,有效节约了CPU费用

3)requestAnimationFrame是由浏览器专门为动画片提供的API,在运转时浏览器会活动优化措施的调用,并且只要页面不是激活状态下的话,动画会自动刹车,有效节约了CPU开支

requestAnimationFrame

本条函数与settimeout很一般,但它是特意为动画片而生的.settimeout经常被用来做动画.大家精晓动画达到60帧,用户就无法感知画面间隔.每一帧大致16微秒.而requestAnimationFrame的帧率刚好是那几个频率.除此之外比较于settimeout,还有以下的有些亮点:

  • requestAnimationFrame
    会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就落成,并且重绘或回流的岁月间隔牢牢追随浏览器的基础代谢频率,一般的话,那几个成效为每秒60帧,每帧大约16微秒.
  • 在隐藏或不可知的要素中,requestAnimationFrame将不会举办重绘或回流,那本来就象征更少的的cpu,gpu和内存使用量。
  • 但它优于set提姆eout/setInterval的地点在于它是由浏览器专门为动画提供的API,在运作时浏览器会自动优化措施的调用,并且只要页面不是激活状态下的话,动画会自动刹车,有效节约了CPU开支。

一句话就是:那玩意性能高,不会卡屏,依照不一致的浏览器自动调整帧率。如若看不懂或者不精通,也从未什么关联,那玩意儿跟浏览器渲染原理有关。大家先学会运用它!

一句话就是:那东西性能高,不会卡屏,依照分歧的浏览器自动调整帧率。即便看不懂或者不了然,也未尝什么关系,那玩意跟浏览器渲染原理有关。大家先学会使用它!

总结:

  1. 浏览器的根本是四线程的,它们在基本制控下互相协作以维持同步,一个浏览器至少已毕多个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。
  2. javascript引擎是按照事件驱动单线程执行的.JS引擎平素等候着任务队列中职务的来临,然后加以处理,浏览器无论哪天都唯有一个JS线程在运作JS程序。
  3. 当界面需求重绘(Repaint)或出于某种操作引发回流(reflow)时,该线程就会履行。但须要小心
    GUI渲染线程与JS引擎是排斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保留在一个连串中等到JS引擎空闲时立刻被执行。
  4. 当一个风浪被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的拍卖。这几个事件可来自JavaScript引擎当前举办的代码块如set提姆eOut、也可来自浏览器内核的其余线程如鼠标点击、AJAX异步请求等,但鉴于JS的单线程关系有着这一个事件都得排队等候JS引擎处理。

    2 赞 11 收藏 1
    评论

亚洲必赢官网 2

怎样行使requestAnimationFrame?

何以拔取requestAnimationFrame?

采用办法跟定时器set提姆eout大约,不一样之处在于,他不需求设置时间间隔参数

运用形式跟定时器set提姆eout大概,分化之处在于,他不需求设置时间距离参数

1         var timer = requestAnimationFrame( function(){
2             console.log( '定时器代码' );
3         } );
1         var timer = requestAnimationFrame( function(){
2             console.log( '定时器代码' );
3         } );

参数是一个回调函数,重返值是一个平头,用来代表定时器的编号.

参数是一个回调函数,重返值是一个整数,用来代表定时器的编号.

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <script>
 9         window.onload = function(){
10             var aInput = document.querySelectorAll( "input" ),
11                 timer = null;
12             aInput[0].onclick = function(){
13                 timer = requestAnimationFrame( function say(){
14                     console.log( 1 );
15                     timer = requestAnimationFrame( say );
16                 } );
17             };
18             aInput[1].onclick = function(){
19                 cancelAnimationFrame( timer );
20             }
21         }
22     </script>
23 </head>
24 <body>
25     <input type="button" value="开启">
26     <input type="button" value="关闭">
27 </body>
28 </html>
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <script>
 9         window.onload = function(){
10             var aInput = document.querySelectorAll( "input" ),
11                 timer = null;
12             aInput[0].onclick = function(){
13                 timer = requestAnimationFrame( function say(){
14                     console.log( 1 );
15                     timer = requestAnimationFrame( say );
16                 } );
17             };
18             aInput[1].onclick = function(){
19                 cancelAnimationFrame( timer );
20             }
21         }
22     </script>
23 </head>
24 <body>
25     <input type="button" value="开启">
26     <input type="button" value="关闭">
27 </body>
28 </html>

cancelAnimationFrame用来关闭定时器

cancelAnimationFrame用来关闭定时器

以此办法要求处理包容: 

那几个主意须要处理包容: 

 不难的极度:

 简单的合作:

1 window.requestAnimFrame = (function(){
2   return  window.requestAnimationFrame       ||
3           window.webkitRequestAnimationFrame ||
4           window.mozRequestAnimationFrame    ||
5           function( callback ){
6             window.setTimeout(callback, 1000 / 60);
7           };
8 })();
1 window.requestAnimFrame = (function(){
2   return  window.requestAnimationFrame       ||
3           window.webkitRequestAnimationFrame ||
4           window.mozRequestAnimationFrame    ||
5           function( callback ){
6             window.setTimeout(callback, 1000 / 60);
7           };
8 })();

如若浏览器都不认识AnimationFrame,就用set提姆eout包容.

假诺浏览器都不认识AnimationFrame,就用set提姆eout包容.

运用3种差其他定时器(set提姆eout, setInterval,
requestAnimationFrame)完成一个进度条的加载

使用3种分化的定时器(set提姆eout, setInterval,
requestAnimationFrame)完毕一个进度条的加载

一、setInterval方式:

一、setInterval方式:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <style>
 9         div{
10             width:0px;
11             height:40px;
12             border-radius:20px;
13             background:#09f;
14             text-align:center;
15             font:bold 30px/40px '微软雅黑';
16             color:white;
17         }
18     </style>
19     <script>
20         window.onload = function(){
21             var oBtn = document.querySelector( "input" ),
22                 oBox = document.querySelector( "div" ),
23                 timer = null, curWidth = 0,
24                 getStyle = function( obj, name, value ){
25                     if( obj.currentStyle ) {
26                         return obj.currentStyle[name];
27                     }else {
28                         return getComputedStyle( obj, false )[name];
29                     }
30                 };
31             oBtn.onclick = function(){
32                 clearInterval( timer );
33                 oBox.style.width = '0';
34                 timer = setInterval( function(){
35                     curWidth = parseInt( getStyle( oBox, 'width' ) );
36                     if ( curWidth < 1000 ) {
37                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
38                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
39                     }else {
40                         clearInterval( timer );
41                     }
42                 }, 1000 / 60 );
43             }
44         }
45     </script>
46 </head>
47 <body>
48     <div>0%</div>
49     <p><input type="button" value="ready!Go"></p>
50 </body>
51 </html>
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <style>
 9         div{
10             width:0px;
11             height:40px;
12             border-radius:20px;
13             background:#09f;
14             text-align:center;
15             font:bold 30px/40px '微软雅黑';
16             color:white;
17         }
18     </style>
19     <script>
20         window.onload = function(){
21             var oBtn = document.querySelector( "input" ),
22                 oBox = document.querySelector( "div" ),
23                 timer = null, curWidth = 0,
24                 getStyle = function( obj, name, value ){
25                     if( obj.currentStyle ) {
26                         return obj.currentStyle[name];
27                     }else {
28                         return getComputedStyle( obj, false )[name];
29                     }
30                 };
31             oBtn.onclick = function(){
32                 clearInterval( timer );
33                 oBox.style.width = '0';
34                 timer = setInterval( function(){
35                     curWidth = parseInt( getStyle( oBox, 'width' ) );
36                     if ( curWidth < 1000 ) {
37                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
38                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
39                     }else {
40                         clearInterval( timer );
41                     }
42                 }, 1000 / 60 );
43             }
44         }
45     </script>
46 </head>
47 <body>
48     <div>0%</div>
49     <p><input type="button" value="ready!Go"></p>
50 </body>
51 </html>

 亚洲必赢官网 3

 亚洲必赢官网 4

 

 

<!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>

<!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>

run code

run code

二、setTimeout方式

二、setTimeout方式

 1 <script>
 2         window.onload = function(){
 3             var oBtn = document.querySelector( "input" ),
 4                 oBox = document.querySelector( "div" ),
 5                 timer = null, curWidth = 0,
 6                 getStyle = function( obj, name, value ){
 7                     if( obj.currentStyle ) {
 8                         return obj.currentStyle[name];
 9                     }else {
10                         return getComputedStyle( obj, false )[name];
11                     }
12                 };
13             oBtn.onclick = function(){
14                 clearTimeout( timer );
15                 oBox.style.width = '0';
16                 timer = setTimeout( function go(){
17                     curWidth = parseInt( getStyle( oBox, 'width' ) );
18                     if ( curWidth < 1000 ) {
19                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
20                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
21                         timer = setTimeout( go, 1000 / 60 );
22                     }else {
23                         clearInterval( timer );
24                     }
25                 }, 1000 / 60 );
26             }
27         }
28     </script>
 1 <script>
 2         window.onload = function(){
 3             var oBtn = document.querySelector( "input" ),
 4                 oBox = document.querySelector( "div" ),
 5                 timer = null, curWidth = 0,
 6                 getStyle = function( obj, name, value ){
 7                     if( obj.currentStyle ) {
 8                         return obj.currentStyle[name];
 9                     }else {
10                         return getComputedStyle( obj, false )[name];
11                     }
12                 };
13             oBtn.onclick = function(){
14                 clearTimeout( timer );
15                 oBox.style.width = '0';
16                 timer = setTimeout( function go(){
17                     curWidth = parseInt( getStyle( oBox, 'width' ) );
18                     if ( curWidth < 1000 ) {
19                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
20                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
21                         timer = setTimeout( go, 1000 / 60 );
22                     }else {
23                         clearInterval( timer );
24                     }
25                 }, 1000 / 60 );
26             }
27         }
28     </script>

三、requestAnimationFrame方式

三、requestAnimationFrame方式

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <style>
 9         div{
10             width:0px;
11             height:40px;
12             border-radius:20px;
13             background:#09f;
14             text-align:center;
15             font:bold 30px/40px '微软雅黑';
16             color:white;
17         }
18     </style>
19     <script>
20         window.onload = function(){
21             var oBtn = document.querySelector( "input" ),
22                 oBox = document.querySelector( "div" ),
23                 timer = null, curWidth = 0,
24                 getStyle = function( obj, name, value ){
25                     if( obj.currentStyle ) {
26                         return obj.currentStyle[name];
27                     }else {
28                         return getComputedStyle( obj, false )[name];
29                     }
30                 };
31             oBtn.onclick = function(){
32                 cancelAnimationFrame( timer );
33                 oBox.style.width = '0';
34                 timer = requestAnimationFrame( function go(){
35                     curWidth = parseInt( getStyle( oBox, 'width' ) );
36                     if ( curWidth < 1000 ) {
37                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
38                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
39                         timer = requestAnimationFrame( go );
40                     }else {
41                         cancelAnimationFrame( timer );
42                     }
43                 } );
44             }
45         }
46     </script>
47 </head>
48 <body>
49     <div>0%</div>
50     <p><input type="button" value="ready!Go"></p>
51 </body>
52 </html>
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <style>
 9         div{
10             width:0px;
11             height:40px;
12             border-radius:20px;
13             background:#09f;
14             text-align:center;
15             font:bold 30px/40px '微软雅黑';
16             color:white;
17         }
18     </style>
19     <script>
20         window.onload = function(){
21             var oBtn = document.querySelector( "input" ),
22                 oBox = document.querySelector( "div" ),
23                 timer = null, curWidth = 0,
24                 getStyle = function( obj, name, value ){
25                     if( obj.currentStyle ) {
26                         return obj.currentStyle[name];
27                     }else {
28                         return getComputedStyle( obj, false )[name];
29                     }
30                 };
31             oBtn.onclick = function(){
32                 cancelAnimationFrame( timer );
33                 oBox.style.width = '0';
34                 timer = requestAnimationFrame( function go(){
35                     curWidth = parseInt( getStyle( oBox, 'width' ) );
36                     if ( curWidth < 1000 ) {
37                         oBox.style.width = oBox.offsetWidth + 10 + 'px';
38                         oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
39                         timer = requestAnimationFrame( go );
40                     }else {
41                         cancelAnimationFrame( timer );
42                     }
43                 } );
44             }
45         }
46     </script>
47 </head>
48 <body>
49     <div>0%</div>
50     <p><input type="button" value="ready!Go"></p>
51 </body>
52 </html>
网站地图xml地图