4 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊
這是個(gè)好問題。我很想說“是”。我不行。
JavaScript通常被認(rèn)為具有腳本(*)可見的單個(gè)執(zhí)行線程,因此當(dāng)輸入內(nèi)聯(lián)腳本、事件偵聽器或超時(shí),您將完全處于控制狀態(tài),直到從塊或函數(shù)的末尾返回。
(*:忽略瀏覽器是否真的使用一個(gè)OS線程來實(shí)現(xiàn)他們的JS引擎,或者其他有限的執(zhí)行線程是否是由WebWorker引入的問題)。
然而,在現(xiàn)實(shí)中不完全是真的以卑鄙的方式。
最常見的情況是立即發(fā)生的事件。當(dāng)您的代碼做了什么事情導(dǎo)致它們時(shí),瀏覽器會(huì)立即觸發(fā)它們:
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">
結(jié)果log in, blur, log out除了IE。這些事件不只是因?yàn)槟愦螂娫抐ocus()直接的,他們可能會(huì)發(fā)生,因?yàn)槟愦螂娫捊oalert(),或者打開一個(gè)彈出窗口,或者其他任何移動(dòng)焦點(diǎn)的東西。
這也可能導(dǎo)致其他事件。例如,添加一個(gè)i.onchange偵聽器并在輸入中鍵入focus()調(diào)用沒有焦點(diǎn),日志順序是log in, change, blur, log out,除了在歌劇院log in, blur, log out, change以及IE在哪里(更難解釋)log in, change, log out, blur.
類似調(diào)用click()元素上,該元素將調(diào)用onclick在所有瀏覽器中立即執(zhí)行處理程序(至少這是一致的!)
(我用的是直接on...事件處理程序?qū)傩?,但同樣發(fā)生在addEventListener和attachEvent.)
還有很多種情況,在這些情況下,您的代碼被線程化時(shí),事件可能會(huì)觸發(fā),盡管您已經(jīng)這樣做了。沒什么挑起它。例如:
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你會(huì)得到一個(gè)模態(tài)對(duì)話框。除非你拒絕那個(gè)對(duì)話,否則不會(huì)再執(zhí)行劇本了,是嗎?沒有。調(diào)整主窗口的大小,您將得到alert in, resize, alert out在文本區(qū)域。
您可能會(huì)認(rèn)為,在模式對(duì)話框打開時(shí),不可能調(diào)整窗口的大小,但并非如此:在Linux中,您可以任意調(diào)整窗口的大?。辉赪indows上,這并不容易,但您可以通過將屏幕分辨率從更大的更改為不適合窗口的更小的分辨率來實(shí)現(xiàn),從而調(diào)整窗口的大小。
你可能會(huì)想,嗯,這只是resize(可能還有更多的scroll),因?yàn)槟_本是線程的,所以當(dāng)用戶沒有與瀏覽器進(jìn)行主動(dòng)交互時(shí),它就會(huì)觸發(fā)。對(duì)于單一窗口,你可能是對(duì)的。但是,當(dāng)你做跨窗口腳本時(shí),這一切都會(huì)被拋到腦后。對(duì)于除Safari之外的所有瀏覽器,在任何一個(gè)瀏覽器繁忙時(shí)都會(huì)阻塞所有窗口/選項(xiàng)卡/框架,您可以從另一個(gè)文檔的代碼中與文檔交互,運(yùn)行在單獨(dú)的執(zhí)行線程中,并導(dǎo)致任何相關(guān)的事件處理程序被觸發(fā)。
當(dāng)模態(tài)彈出時(shí)( alert
,confirm
,prompt
在除Opera之外的所有瀏覽器中都是開放的; 期間 showModalDialog
在支持它的瀏覽器上; “這頁上的劇本可能很忙.”對(duì)話框,即使你選擇讓腳本繼續(xù)運(yùn)行,允許像調(diào)整大小和模糊事件觸發(fā)和處理,即使腳本是在繁忙的循環(huán)中間,除了在Opera。 不久前,對(duì)于我來說,在IE中使用Sun Java插件,調(diào)用applet上的任何方法都可能允許事件觸發(fā)并重新輸入腳本。這一直是一個(gè)時(shí)間敏感的錯(cuò)誤,有可能Sun已經(jīng)修復(fù)了它(我當(dāng)然希望如此)。 可能更多。我已經(jīng)有一段時(shí)間沒有對(duì)此進(jìn)行測(cè)試了,從那時(shí)起瀏覽器就變得越來越復(fù)雜了。
setInterval
postMessage

TA貢獻(xiàn)1779條經(jīng)驗(yàn) 獲得超6個(gè)贊
(給其他人的評(píng)論:setTimeout/setInterval

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超4個(gè)贊

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個(gè)贊
添加回答
舉報(bào)