js高手之路,的黑魔法

set提姆eout 的黑魔法

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

原稿出处:
李三思   

set提姆eout,前端工程师必定会打交道的一个函数.它看起来卓殊的简要,朴实.有着一个很不平庸的名字–定时器.让年少的自己天真的认为自己可以决定将来.却不知朴实之中隐含着惊天大密.我还记得我首先次用那些函数的时候,我天真的以为它就是js完毕二十四线程的工具.当时用它落成了一个坦克大战的小游戏,玩儿不亦和讯.但是随着在前端那条路上越走越远,对它了然起来发生了变化.它好似开端蒙上了面纱,时常有一些出人意表的变现让自身捉摸不透.终于,我的耐性耗尽,下定狠心,要摘除它的面具,一探讨竟.

要说set提姆eout的根子,就得从它的法定概念说起.w3c是那般定义的

setTimeout() 方法用于在指定的飞秒数后调用函数或总计说明式。

看来这么一个认证,我们清楚了它就是一个定时器,大家设定的函数就是一个”闹钟”,时间到了它就会去执行.但是聪明的您忍不住有诸如此类一个问号,若是是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上面对应的小方块代表该时间点的任务。

js高手之路,的黑魔法。 

t1时刻:

 

GUI渲染线程

浏览器事件触发线程:

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

定时触发线程:

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

在那t1的时日段内,继鼠标点击事件触发后,先前已安装的setTimeout定时也抵达了,此刻对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引擎当前实践的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系有所那一个事件都得排队等待JS引擎处理。

    2 赞 11 收藏 1
    评论

澳门葡京 2

怎么样利用requestAnimationFrame?

怎么行使requestAnimationFrame?

运用方法跟定时器set提姆eout大约,不一样之处在于,他不要求设置时间距离参数

使用办法跟定时器setTimeout大约,不相同之处在于,他不必要安装时间距离参数

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>

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website