如何確保JavaScript的執(zhí)行順序 之jQuery.html深度分析
我們先來簡單回顧下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.調(diào)試,單步跟進
逐行分析jQuery源代碼是一件相當枯燥的事情。我這里會以test2.htm為目標,調(diào)試進入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函數(shù)的最后一個條件分支

來看看append函數(shù):
3) 進入domManip函數(shù)
繼續(xù)單步調(diào)試,發(fā)現(xiàn)目標,這里有對scripts的長度判斷:
應該是已經(jīng)分析了輸入字符串,并提取了其中的script標簽,我們來看下這里的局部變量scripts的內(nèi)容:
4)發(fā)現(xiàn)目標
這里的兩個局部變量scripts和evalScript是我們重點需要關(guān)注的,我們分別來看下:
scripts,這是一個數(shù)組,包含兩個script標簽:
[<script src="./service.ashx?file=js/jquery-ui.js&delay=2000" type="text/javascript"></script>
, <script>alert(typeof(jQuery.ui));</script>]
evalScript,這是一個函數(shù),通過jQuery.each函數(shù)來調(diào)用,上述數(shù)組中的每個值都會作為參數(shù)傳到這個函數(shù)中執(zhí)行:
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函數(shù)會首先把其中的script檢索出來,然后對于每個script標簽應用evalScript函數(shù)。
在這個函數(shù)中,對于外部JavaScript個內(nèi)聯(lián)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)。這也是在各種不同瀏覽器中能夠保證動態(tài)JS的加載順序的關(guān)鍵所在。
2)jQuery.html如何處理字符串中的內(nèi)聯(lián)script標簽
jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
來看下globalEval函數(shù)的定義:
由此可見,對于內(nèi)聯(lián)的script標簽,jQuery通過在head中創(chuàng)建script標簽來執(zhí)行。
4. 后記
目前來看,一切來龍去脈似乎清晰可見。那么大家有沒有考慮過,如果動態(tài)加載加載不同域名下(Cross-Domain)的JavaScript文件,jQuery還能確保在所有瀏覽器下的JavaScript的執(zhí)行順序嗎?
也就是說在當前流行的靜態(tài)資源的CDN加速情況下,jQuery.html是不是一個完全之策呢?
請看下篇 如何確保JavaScript的執(zhí)行順序 - 之jQuery.html并非萬能鑰匙。待續(xù)。。。
- 淺談js在html中的加載執(zhí)行順序,多個jquery ready執(zhí)行順序
- 簡述jQuery ajax的執(zhí)行順序
- jquery中ajax函數(shù)執(zhí)行順序問題之如何設置同步
- Jquery ajax執(zhí)行順序 返回自定義錯誤信息(實例講解)
- jQuery中(function(){})()執(zhí)行順序的理解
- jquery $.ajax各個事件執(zhí)行順序
- jQuery中triggerHandler()方法用法實例
- jquery的trigger和triggerHandler的區(qū)別示例介紹
- jQuery事件模型默認行為執(zhí)行順序及trigger()與 triggerHandler()比較實例分析
相關(guān)文章
jQuery Easyui Tabs擴展根據(jù)自定義屬性打開頁簽
這篇文章主要介紹了jQuery Easyui Tabs擴展根據(jù)自定義屬性打開頁簽的實現(xiàn)代碼,首先增加擴展,接著點擊事件open方法實現(xiàn)easyui tabs擴展,非常不錯,需要的朋友可以參考下2016-08-08jQuery學習筆記之jQuery.extend(),jQuery.fn.extend()分析
給jQuery做過擴展或者制作過jQuery插件的人這兩個方法東西可能不陌生. jQuery.extend([deep],target,object1,,object2...[objectN]) jQuery.fn.extend([deep],target,object1,,object2...[objectN]) 這兩個屬性都是用于合并兩個或多個對象的屬性到target對象.2014-06-06jQuery實現(xiàn)Email郵箱地址自動補全功能代碼
這篇文章主要介紹了jQuery實現(xiàn)Email郵箱地址自動補全功能代碼,涉及jQuery鼠標事件及字符操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11jQuery獲取訪問者IP地址的方法(基于新浪API與QQ查詢接口)
這篇文章主要介紹了jQuery獲取訪問者IP地址的方法,實例分析了jQuery基于新浪API與QQ查詢接口獲取來訪者IP的相關(guān)參數(shù)傳遞與數(shù)據(jù)處理技巧,需要的朋友可以參考下2016-05-05