setTimeout延時0毫秒的做用

wizardpisces經驗:javascript

這幾天作web動畫,用到css3的animation,爲了對一個存在的元素觸發動畫,能夠經過添加className,但是隻能觸發一次,爲了觸發屢次我嘗試了先刪除className後直接添加的方法,失敗了,最後我經過刪除和建立元素得以實現再添加className得以實現,看完這篇文章,經過先刪除元素className再setTimeout(添加元素的className,時間),得以實現屢次觸發效果,不過最後的原理仍是有點模糊,若是各位有新穎的看法,但願不吝賜教。2014/7/25號BOSS說setTimeout會被線程放在堆棧底,與這篇文章解釋有所差別。setTimeout好像有種強制重繪的能力css

原文:html

常常看到setTimeout延時0ms的javascript代碼,感到很迷惑,難道延時0ms和不延時不是一個道理嗎?後來經過查資料以及實驗得出如下兩個做用,可能還有做用我還不知道,但願得知的朋友在後面評論上不吝指出。
一、實現javascript的異步;
正常狀況下javascript都是按照順序執行的。可是咱們可能讓該語句後面的語句執行完再執行自己,這時就能夠用到setTimeout延時0ms來實現了。
如: 
alert(1); 
setTimeout("alert(2)", 0); 
alert(3); 
雖然延時了0ms,可是執行順序爲:1,3,2 
這樣就保證setTimeout裏面的語句在某一代碼段中最後執行。 


二、在事件中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執行,以及完成文檔當前狀態更新後,告訴瀏覽器去啓用 setTimeout 內註冊的函數。
 舉個例子來講這句話的意思,假如當某個事件在頁面上創建一個文本框,並給文本框賦值(完成文檔當前狀態更新),而後將焦點定到文本框,而且選中文本框的內容(後面部分就須要用到setTimeout 延遲0ms實現,不然很差實現)。
先看個例子:
java

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

 <html>

 <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>setTimeout</title>

 <script type="text/javascript" >
(function(){
 
 function get(id){
  return document.getElementById(id);
 }
 
 window.onload = function(){
  get('makeinput').onmousedown = function(){
   var input = document.createElement('input');
   input.setAttribute('type', 'text');
   input.setAttribute('value', 'test1');
   get('inpwrapper').appendChild(input);
   input.focus();
   input.select();
  }
  get('makeinput2').onmousedown = function(){
   var input = document.createElement('input');
   input.setAttribute('type', 'text');
   input.setAttribute('value', 'test1');
   get('inpwrapper2').appendChild(input);
   setTimeout(function(){
    input.focus();
    input.select();
   }, 0);
  }
  get('input1').onkeypress = function(){
   get('preview1').innerHTML = this.value;
  }
  get('input2').onkeypress = function(){
                               setTimeout(function(){
   get('preview2').innerHTML = get('input2').value;
                              },0 );
  }
 }
})();

</script>

</head>

<body>
<h1><code>DEMO1</code></h1>
<h2>一、未使用 <code>setTimeout</code>(未選中文本框內容)</h2>
<button id="makeinput">生成 input</button>
<p id="inpwrapper"></p>
<h2>二、使用 <code>setTimeout</code>(當即選中文本框內容)</h2>
<button id="makeinput2">生成 input</button></h2>
<p id="inpwrapper2"></p>

--------------------------------------------------------------------------
<h1><code>DEMO2</code></h1>
<h2>一、未使用 <code>setTimeout</code>(只有輸入第二個字符時,前一個字符才顯示出來)</h2>
<input type="text" id="input1" value=""/><div id="preview1"></div>
<h2>二、使用 <code>setTimeout</code>(輸入時,字符同時顯示出來)</h2>

<input type="text" id="input2" value=""/><div id="preview2"></div>

</body>

</html>


運行示例
現有的 JavaScript 引擎是單線程處理任務的。它把任務放到隊列中,不會同步去執行,必須在完成一個任務後纔開始另一個任務。其實,這是一個把須要執行的任務從隊列中跳脫的技巧。在DEMO1中,JavaScript 引擎在執行 onmousedown時,因爲沒有多線程的同步執行,不可能同時去處理剛建立元素的 focus 和 select 方法,因爲這兩個方法都不在隊列中,在完成 onmousedown 後,JavaScript 引擎已經丟棄了這兩個任務,正如第一種狀況。而在第二種狀況中,因爲setTimeout能夠把任務從某個隊列中跳脫成爲新隊列,於是可以獲得指望的結果。css3

相關文章
相關標籤/搜索