4 回答

TA貢獻1829條經驗 獲得超13個贊
這是個好問題。我很想說“是”。我不行。
JavaScript通常被認為具有腳本(*)可見的單個執行線程,因此當輸入內聯腳本、事件偵聽器或超時,您將完全處于控制狀態,直到從塊或函數的末尾返回。
(*:忽略瀏覽器是否真的使用一個OS線程來實現他們的JS引擎,或者其他有限的執行線程是否是由WebWorker引入的問題)。
然而,在現實中不完全是真的以卑鄙的方式。
最常見的情況是立即發生的事件。當您的代碼做了什么事情導致它們時,瀏覽器會立即觸發它們:
var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
l.value+= 'blur\n';
};
setTimeout(function() {
l.value+= 'log in\n';
l.focus();
l.value+= 'log out\n';
}, 100);
i.focus();
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">
結果log in, blur, log out除了IE。這些事件不只是因為你打電話focus()直接的,他們可能會發生,因為你打電話給alert(),或者打開一個彈出窗口,或者其他任何移動焦點的東西。
這也可能導致其他事件。例如,添加一個i.onchange偵聽器并在輸入中鍵入focus()調用沒有焦點,日志順序是log in, change, blur, log out,除了在歌劇院log in, blur, log out, change以及IE在哪里(更難解釋)log in, change, log out, blur.
類似調用click()元素上,該元素將調用onclick在所有瀏覽器中立即執行處理程序(至少這是一致的!)
(我用的是直接on...事件處理程序屬性,但同樣發生在addEventListener和attachEvent.)
還有很多種情況,在這些情況下,您的代碼被線程化時,事件可能會觸發,盡管您已經這樣做了。沒什么挑起它。例如:
var l= document.getElementById('log');
document.getElementById('act').onclick= function() {
l.value+= 'alert in\n';
alert('alert!');
l.value+= 'alert out\n';
};
window.onresize= function() {
l.value+= 'resize\n';
};
<textarea id="log" rows="20" cols="40"></textarea>
<button id="act">alert</button>
命中alert你會得到一個模態對話框。除非你拒絕那個對話,否則不會再執行劇本了,是嗎?沒有。調整主窗口的大小,您將得到alert in, resize, alert out在文本區域。
您可能會認為,在模式對話框打開時,不可能調整窗口的大小,但并非如此:在Linux中,您可以任意調整窗口的大??;在Windows上,這并不容易,但您可以通過將屏幕分辨率從更大的更改為不適合窗口的更小的分辨率來實現,從而調整窗口的大小。
你可能會想,嗯,這只是resize(可能還有更多的scroll),因為腳本是線程的,所以當用戶沒有與瀏覽器進行主動交互時,它就會觸發。對于單一窗口,你可能是對的。但是,當你做跨窗口腳本時,這一切都會被拋到腦后。對于除Safari之外的所有瀏覽器,在任何一個瀏覽器繁忙時都會阻塞所有窗口/選項卡/框架,您可以從另一個文檔的代碼中與文檔交互,運行在單獨的執行線程中,并導致任何相關的事件處理程序被觸發。
當模態彈出時( alert
,confirm
,prompt
在除Opera之外的所有瀏覽器中都是開放的; 期間 showModalDialog
在支持它的瀏覽器上; “這頁上的劇本可能很忙.”對話框,即使你選擇讓腳本繼續運行,允許像調整大小和模糊事件觸發和處理,即使腳本是在繁忙的循環中間,除了在Opera。 不久前,對于我來說,在IE中使用Sun Java插件,調用applet上的任何方法都可能允許事件觸發并重新輸入腳本。這一直是一個時間敏感的錯誤,有可能Sun已經修復了它(我當然希望如此)。 可能更多。我已經有一段時間沒有對此進行測試了,從那時起瀏覽器就變得越來越復雜了。
setInterval
postMessage

TA貢獻1779條經驗 獲得超6個贊
(給其他人的評論:setTimeout/setInterval

TA貢獻1827條經驗 獲得超8個贊
添加回答
舉報