前言:從《原生JS實現輪播(上)》中JS實現漸變效果,引出的setTimeout
用法問題。
對于setInterval
比較熟悉,但對于setTimeout
,因為用得少,不夠了解,總覺得有一層神秘的面紗待揭開。
1.setTimeout
實現setInterval
效果
showTime();
function showTime(){
var today = new Date();
document.write("The time is: " + today.toString());
document.write("<br />");
setTimeout("showTime()", 5000); //調用自身
}
和setInterval
的區別?這個還待深究。
2.JavaScript引擎單線程
瀏覽器多線程/循環阻塞/事件循環模型(這幾個概念待了解)
問題:
<script type="text/javascript">
var start = new Date;
setTimeout(function(){
var end = new Date;
console.log('Time elapsed:', end - start, 'ms');
}, 500);
while (new Date - start < 1000) {};
</script>
輸出的結果并不是期望的Time elapsed: 500 ms
,而是大于1000ms的。因為JS是單線程的,while完成后(執行了1000ms),達到了執行setTimeout的條件了才執行。也就是說,對setTimeout中匿名函數的實際調用被while()循環阻塞了,實際的調用在while()循環阻塞結束后才真正執行。
3.延遲時間為0
<script>
console.log('a');
setTimeout(function(){
console.log('b');
},0);
console.log('c');
console.log('d');
</script>
顯示的結果是:acdb,因為即使延遲時間為0,瀏覽器也是有默認最小的延遲時間的,如HTML5定義的最小時間間隔是4毫秒。即使我們把setTimeout的毫秒數設置為0,被調用的程序也不會馬上啟動。
4.setTimeout
實現動畫
例子:
<div id="container" style="width:100px;height:100px;border:1px solid black;"></div>
<div id="btn" style="width:40px;height:40px;line-height:40px;margin-top:20px;background:pink;">click</div>
<script>
window.onload = function(){
var con = document.getElementById('container');
var btn = document.getElementById('btn');
//Params: i 為起始高度,num為預期高度
function render(i, num) {
i++;
con.style.height = i + 'px';
//亮點在此
if(i < num){
setTimeout(function() {
render(i, num); //這里調用自身而循環執行
},0);
}
else {
con = null;
btn = null;
}
};
btn.onclick = function(){
render(100, 200);
};
};
</script>
5.setTimeout
實現捕獲事件
例子(捕獲事件又給自己挖了個坑)
<div id="parent" style="width:100px;height:100px;border:1px solid black;">
<div id="child" style="width:50px; height:50px; background-color:#fcc;"></div>
</div>
<script>
//點擊子元素,實現子元素的事件在父元素觸發后觸發
window.onload = function(){
var parent = document.getElementById('parent');
var child = document.getElementById('child');
parent.onclick = function(){
console.log('parent');
}
child.onclick = function(){
//利用setTimeout,冒泡結束后,最后輸出child
setTimeout(function(){
console.log('child');
},0);
}
parent = null; //不知為何這句無效
child = null; //不知為何這句無效
}
</script>
6.setTimeout
中的this
這個等研究this
的時候一起,又挖了個坑。。
參考文章
http://www.cnblogs.com/giggle/p/5346531.html
http://www.cnblogs.com/Medeor/p/4945687.html