定时器基础
1 2 3 4 5 6 7 8 9
| var timer1 = setTimeout(function(){
}, 1000); console.log(timer1); //=> 1
var timer2 = setInterval(function(){
}, 1000); console.log(timer2); //=> 2
|
- 定时器的返回值: 当我们设置定时器(不管是setTimeout还是setInterval),都会有一个返回值,返回值是一个数字,代表当前实在浏览器中设置的第几个定时器(返回的是定时器序号)
- setTimeout和setInterval虽然是处理不同需求的定时器,但是都是浏览器的定时器,所以设置的时候,返回的序号是依次排列的
- setInterval设置完成定时器会有一个返回值,不管执行多少次,这个代表序号的返回值不变(设置定时器就有返回值,执行多少次是定时器的处理)
清除定时器
- clearTimeout([定时器排队序号])
- clearInterval([定时器排队序号])
- 定时器需要手动清除
1 2 3 4 5 6
| var t1 = setTimeout(function(){ clearInterval(t1); t1 = null; }, 1000);
|
实现动画效果
1 2 3 4 5 6 7 8 9 10 11 12
| function imgFade(curImg){ var n = 0; var timer = setInterval(function(){ if(n > 1){ clearInterval(timer); timer = null; return; } n += 0.05; utils.css(curImg, 'opacity', n); }, 17); //=> 17ms是执行定时器动画相对比较理想的时间间隔 }
|
JS中的同步和异步编程
JS是单线程的(一次只能执行一个任务,当前任务没有完成,下面任务不进行处理)
同步编程(sync:synchronize):任务是按照顺序一件件的完成的,当前任务没有完成,下面的任务部进行处理
异步编程(async)当前任务再等待执行的时候,我们不去执行,继续完成下面的任务,当下面的任务完成后,而是也到达等待的时间了,采取完成当前的任务
定时器都是异步编程的
所有的时间绑定都是异步编程的
AJAX中有异步编程
有些人把回调函数当作异步编程(牵强)
1 2 3 4 5 6 7 8 9
| var startTime = new Date(); for(var i = 0; i < 1000000; i += 1){ if(i === 999999){ console.log('no'); } } console.log(new Data() - startTime); console.log('ok');
|
1 2 3
| while(1===1){} console.log(1);
|
1 2 3 4 5 6
| var n = 0; setTimeout(function(){ n++; console.log(n); }, 1000); console.log(n);
|
同步异步编程的核心原理
- JS中有两个任务队列(存放任务列表的空间就是任务队列)
- 1、主任务队列:同步执行任务(从上到下一次执行)
2、等待任务队列:异步执行任务(主任务队列中的任务全部完成,把等待任务队列中的任务拿到主任务队列中执行(哪一个先到,先找哪一个,同时到,按照创建顺序来),当前这个任务完成后,再到等待中去找其他任务)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| setTimeout(function(){ console.log(1); }, 50);
setTimeout(function(){ console.log(2); }, 10);
setTimeout(function(){ console.log(3); }, 30);
for(var i = 0; i < 100000000; i += 1){ if(i === 99999999){ console.log(4); } }; console.log(5);
|
JS中固定步长和固定时间的匀速运动动画
1、步长固定(每走一步多少固定),但是多长时间运动完成不固定
1 2 3 4 5 6 7 8 9 10 11 12 13
| var oBox = document.getElementById('box'), target = document.documentElement.clientWidth - oBox.offsetWidth; //=> 动画:每隔一段时间都在自己原有的left基础上累加步长10排序,一直到达目标值结束 var timer = setInterval(function(){ var curL = oBox.offsetLeft; curL += 10; oBox.style.left = curL + 'px'; if(curL >= target){ oBox.style.left = target + 'px'; clearInterval(timer); timer = null; } }, 17);
|
2、固定时间的匀速动画
- target: 目标值
- start: 起始值
- change:总距离 target-start
- duration: 总时间
- time:已经运动的时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function linear(time, begin, change, duration){ return time/duration*change + begin } var oBox = document.getElementById('box'), time = 0, duration = 1000, begin = parseInt(getComputedStyle(oBox).left), target = document.documentElement.clientWidth - oBox.offsetWidth, change = target - begin; var timer = setInterval(function(){ time += 17; var curL = linear(time, begin, change, duration); if(time >= duration){ clearInterval(timer); timer = null; curL = target; } oBox.style.left = curL + 'px'; }, 17);
|
多方向固定时间匀速运动
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; }
.box { width: 100px; height: 100px; position: absolute; left: 0; top: 0; background: #ff6700; } </style> </head> <body> <div class="box"></div> <script> var box = document.getElementsByClassName('box')[0]; var time = 0, duration = 1000; var begin = { left: box.offsetLeft, top: box.offsetTop, opacity: 1 }; var target = { left: document.body.clientWidth - box.offsetWidth, top: document.body.clientHeight - box.offsetHeight, opacity: 0.2 }; var change = {}; for(var key in target){ if(target.hasOwnProperty(key)){ change[key] = target[key] - begin[key]; } }
function linear(t, b, c, d){ return t / d * c + b; }
box.timer = setInterval(function(){ if(time >= duration-17){ box.style.left = target.left + 'px'; box.style.top = target.top + 'px'; clearInterval(box.timer); return; } time += 17; var curPos = {}; for(var key in change){ curPos[key] = linear(time, begin[key], change[key], duration); }
for(var key in curPos){ if(key !== 'opacity'){ box.style[key] = curPos[key] + 'px'; }else{ box.style[key] = curPos[key]; } } }, 17) </script> </body> </html>
|