往頁面上插入一個script元素使用創建元素的方式或者document.write的方式有何區別?

兩種方式往頁面上插入一個script元素:

1)document.write的方式:

document.write("&

var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://www.example.com/1.js");
document.getElementsByTagName("head")[0].appendChild(script);

這兩種方式各有什麼限制?有何優劣?


在瀏覽器通過網路下載一個HTML文件時,需要做2個基本的事情:解析HTML流、構建DOM樹

解析HTML流即將HTML字元流變為一個語法可識別的token集合,說白了就是語法解析,隨後基於解析後的token再形成我們熟知的DOM樹

如果使用document.write寫入一個元素(無論是否是script),會造成HTML流被修改,此時瀏覽器需要額外做解析的工作,才可以繼續DOM樹的構建

而如果使用創建元素並append的方式,則只有DOM樹發生變動,不需要額外的解析工作

除此之外,document.write出來的腳本會立即下載即行(同步阻塞),這會阻塞後續DOM的構建,如果這個腳本因網路等原因下載比較慢,頁面就會處於半

但是如果在後面有其它腳本依賴於你寫入的script,那麼使用document.write是一個比較好的選擇,直接創建元素會導致非同步讓後續有依賴的腳本執行出錯

再者,當頁面已經完成載入(DOMContentLoaded事件觸發)時,HTML流會被關閉,此時無法使用document.write,如果強制使用會使得原來的頁面消失,這個大部分人都明白

最後,低版本的IE瀏覽器(如IE6)下,document.write寫入的腳本執行時機是錯誤的,其時機控制非常複雜,如果你對腳本的執行順序有要求的話,這一兼容性問題會讓你頭疼,這裡摘錄我以前做出的總結

/*
* 在IE下,document.write執行的順序會錯亂
* 假設使用document.write寫入script標籤,順序為a1-&>a2-&>a3,並在a3中定義了變數hello
* 則同樣使用document.write寫入b1腳本,無法讀取hello
* 必須使用至少對應的3層嵌套,形成b1-&>b2-&>b3順序的document.write,在b3中讀取hello變數才可行
* 因此,使用checkAdStatus函數自調用遞歸5層來讀取全局的BAIDU_CLB_adRendered變數
*
* 如果在5層嵌套沒到的情況下發現BAIDU_CLB_adRendered已經被賦值,則可以提前退出
*/

當然採用appendChild的方式也會有兼容性問題,比如乾脆沒有&標籤,或者IE6下的&標籤未閉合會吞兄弟節點這種奇怪的事情……


兩者的目的都是想 非同步載入js文件

document.write : 只是在ie中 對非同步有效 其他都會是同步載入 阻擋後面元素的載入

第二種 就是通用的非同步載入了

還有一種就是利用一個 get請求 去載入 jquery的getscript就是如此

這是簡單的理解了

其實如果不考慮以上 從語法來看:

第一種叫: 拼接html字元串形式

第二種: dom插入方式

個人比較喜歡 第一種。 有人說 第二種 比較『正規』。不過總感覺這樣更形式化


推薦閱讀:

想深入了解一下 jQuery 的源碼,但是覺得學習曲線有點陡峭,有沒什麼好的方法或者學習資源推薦?
通過w3school初步學習了html,css,js和jQ,自知自己對css,js,jQ的學習還不到位~該怎麼去提升?
後端渲染html、前端模板渲染html,jquery的html,各有什麼區別?

TAG:前端開發 | JavaScript | jQuery | DOM |