上一篇:[原創]如何確保JavaScript的執行順序 – 之實戰篇1. 引言
在上一篇文章《如何確保JavaScript的執行順序 - 之實戰篇》中,我們發現jQuery的html函數能夠確保動態載入的JavaScript按照引入順序執行。
我們先來簡單回顧下HTML原始碼(test2.htm):
<html>
<head>
<title></title>
<script src="js/jquery-1.4.4.js" type="text/javascript"></script>
<script>
$(function(){
$('#container').html('<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text\/javascript"><\/script>' + '<script>alert(typeof(jQuery.ui));<\/script>');
});
</script>
</head>
<body>
<div id="container">
</div>
</body>
</html>
2. 調試,單步跟進
逐行分析jQuery原始碼是一件相當枯燥的事情。我這裡會以test2.htm為目標,調試進入jQuery原始碼。
1) 首先在html: 打一個斷點,重新整理頁面
這裡的value是字串:"<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script><script>alert(typeof(jQuery.ui));</script>"
我們來看會進入那個條件分支:首先看看rnocache是啥?
可見value中含有 <script 字串,不會進入第二個條件分支。
2) 進入html函數的最後一個條件分支
來看看append函數:
3) 進入domManip函數
繼續單步調試,發現目標,這裡有對scripts的長度判斷:
應該是已經分析了輸入字串,並提取了其中的script標籤,我們來看下這裡的局部變數scripts的內容:
4) 發現目標
這裡的兩個局部變數scripts和evalScript是我們重點需要關注的,我們分別來看下:
scripts,這是一個數組,包含兩個script標籤:
[<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script>
, <script>alert(typeof(jQuery.ui));</script>]
evalScript,這是一個函數,通過jQuery.each函數來調用,上述數組中的每個值都會作為參數傳到這個函數中執行:
function evalScript( i, elem ) {
if ( elem.src ) {
jQuery.ajax({
url: elem.src,
async: false,
dataType: "script"
});
} else {
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
3. 哦,明白了
通過上面的分析,我們清楚的看到jQuery.html函數會首先把其中的script檢索出來,然後對於每個script標籤應用evalScript函數。
在這個函數中,對於外部JavaScript個內聯JavaScript,進行了不同的處理。
1) jQuery.html如何處理字串中的外部script標籤
jQuery.ajax({
url: elem.src,
async: false,
dataType: "script"
});
對於外部script標籤,比如:<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script>,jQuery採用了同步Ajax方案(async: false)。這也是在各種不同瀏覽器中能夠保證動態JS的載入順序的關鍵所在。
2) jQuery.html如何處理字串中的內聯script標籤
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
來看下globalEval函數的定義:
由此可見,對於內聯的script標籤,jQuery通過在head中建立script標籤來執行。
4. 後記
目前來看,一切來龍去脈似乎清晰可見。那麼大家有沒有考慮過,如果動態載入載入不同網域名稱下(Cross-Domain)的JavaScript檔案,jQuery還能確保在所有瀏覽器下的JavaScript的執行順序嗎?
也就是說在當前流行的靜態資源的CDN加速情況下,jQuery.html是不是一個完全之策呢?
請看下篇 如何確保JavaScript的執行順序 - 之jQuery.html並非萬能鑰匙。待續。。。