2012-02-23 15 views
5

我試圖發現不管是正在執行同步包括了當前JavaScript文件(通過楷書標籤)如何檢測是否被列入你的Javascript同步或異步

<script src="myscript.js"></script> 

或異步通過插入腳本元素到DOM編程,像

var script = document.createElement('script') 
script.src = 'myscript.js' 
document.body.appendChild(script) 

,因此是否document.write可以使用或不使用。我已經想出了一個瘋狂的解決方案,測試document.write是否有效,請參閱this gist

基本上,它通過使用document.write寫出一個元素 - 我選擇了一個空的腳本標記。然後它查詢DOM以確定該腳本元素是否已成功寫出。如果是 - 腳本必須同步包含,否則包含異步。

此解決方案適用於目前爲止我測試過的所有瀏覽器(所有主要的瀏覽器,包括IE7 +),Opera除外。

問題是:有沒有更好的解決方案?

注意:我也試過檢查document.readyState,但這在IE中似乎沒有幫助。

另請注意:我不需要document.write是邪惡的講座。我知道。

更新:原來,除了沒有工作的歌劇,我的技術也靠不住在IE和其他瀏覽器某些情況下 - document.write可能會或可能不會因時間或緩存的情況下工作。 spec似乎同樣多。

+2

你確定你不需要演講?我已準備好給你一個...:P – Domenic 2012-02-23 04:35:04

回答

1

這是邪惡的,但你可以重新定義文檔功能並編寫自己的。像這樣也許:

var oldAppendChild = document.body.appendChild; 

document.body.appendChild = function(child) { 
    //examine if child is a script element, do stuff with it if it is 
    //finally do what the original function did and: 
    oldAppendChild(child); 
} 
當然

你需要處理各種不同的瀏覽器怪癖和所有的不同的方式之一可能腳本元素添加到頁面,但它是什麼你描述

替代
+0

我不知道這是如何幫助我檢測腳本是如何包含的。我似乎誤解了我的 – airportyh 2012-02-23 04:47:35

+1

啊。你想讓*執行*腳本知道*本身*是如何被包含的? – 2012-02-23 04:52:09

+0

是的,就是這樣。 – airportyh 2012-02-24 04:53:50

1

如果你完全控制了所有的方面,你可以使用JS的動態服務器頁面,並根據需要查詢URL的參數,然後用它在腳本中設置一個變量。

var script = document.createElement('script'); 
script.src = 'myscript.php?type=asynch'; 
document.body.appendChild(script); 

也許可以通過檢查腳本元素的「src」屬性做這一切的客戶端,但我不是陽性。

+0

是的,可以工作。您的腳本將需要遍歷所有腳本元素並通過URL匹配來查找匹配項。我希望不必走這條路。 – airportyh 2012-02-24 14:08:20

+0

如果我的回答是有用或正確的,請接受它,以便我可以獲得積分。點擊答案旁邊的複選標記即表示接受。 – 2012-03-03 05:03:01

0

那麼,這裏是一個快速和骯髒的解決方案。我們假設如果DOMContentLoaded事件已經觸發,包含所有腳本的整個文檔已經被加載。如果您的腳本在此之前執行過,則它已按您的定義執行排序'同步'。如果之後執行,則必須通過另一種方式加載('異步地')。

再次,快速和骯髒:在你的HTML文件中創建一個腳本標記在你的頭;爲了兼容跨瀏覽器,我相信它必須是html文件中的第一個腳本標記(注意:如果在現代瀏覽器中未定義,則window.DOMready是falsey)。

<script> 
// this property by default is false 
window.DOMready = false; 

// all browsers but IE<8 
// wait for the DOMContentLoaded event and set window.DOMready to true 
if (document.addEventListener) { 
    document.addEventListener("DOMContentLoaded", function() { 
     window.DOMready = true; 
    }, false); 

} else { 
    // not entirely accurate but functioning in IE<8 
    // you may want to use another IE solution if you care 
    window.onload = function() { 
     window.DOMready = true; 
    } 
} 
</script> 

然後,在您的腳本文件中,您可以檢查window.DOMready屬性。如果爲true,那麼腳本已被異步加載。例如:

// myscript.js 
if (window.DOMready) { 
    // we have been loaded asynchroneously 
} else { 
    // we have been loaded synchroneously 
} 

享受!

+0

這不會真正起作用,因爲異步腳本可以在domready之前完成加載,例如,如果頁面底部附近有緩慢加載的腳本。 – airportyh 2012-02-24 14:19:05

+0

腳本可以在任何時候執行 - 您通常會等待dom準備好使用助手庫(如jquery),以便確保您的目標元素實際上位於DOM中。 – 2012-07-20 08:07:23