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