2012-07-18 41 views
4

我想知道什麼時候使用基於DOM的生成與.innerHTML或使用JQuery的.append方法附加字符串?我在這裏閱讀了一篇相關的文章Should you add HTML to the DOM using innerHTML or by creating new elements one by one?,但我仍然不確定每種方法的用例。它只是一個性能問題,我總是選擇一個而不是另一個。何時使用基於DOM的生成與使用字符串/ innerHTML/JQuery生成DOM內容?

假設形式是任意變量:

DOM代

  var div = document.createElement("div"), 
      label = document.createElement("label"), 
      input = document.createElement("input"); 

      div.appendChild(label); 
      div.appendChild(input); 

      form.appendChild(div); 

JQuery的

  $(form).append("<div><label></label><input></input></div>") 
+0

看看這兩個代碼示例,並看到第二個不僅更短,更可讀和更快,我看不出任何理由去直接DOM操作。 – Oded 2012-07-18 21:17:26

+0

關閉''標籤?這有效嗎? – 2012-07-18 22:24:48

回答

-1

這僅僅是一個性能問題。選擇最適合你的那個。

jsPerf充滿這些性能測試的,像這樣的:test

+0

這絕對不只是表現的問題。還有很多其他問題需要考慮:安全性,靈活性,客戶端 - 服務器的可移植性,簡單性,事件綁定,組件安裝...... – 2013-12-13 16:21:30

4

;二是更具可讀性,雖然這是來自jQuery的該做的innerHTML爲你工作。在香草JS,它會是這樣的:

form.insertAdjacentHTML("beforeend", "<div><label></label><input></input></div>"); 

......我甚至認爲甚至擊敗jQuery。雖然,你應該不擔心表現。性能總是取決於要插入的節點數量 - 對於單個解析器,HTML解析器比直接創建它們要慢,對於大型HTML字符串,本地解析器比腳本更快。如果你真的擔心性能,你將需要測試,測試和測試(並且我會說你的應用出了問題)。

然而,這兩種方法之間有很大的區別:使用#1,您有三個變量引用了DOM元素。例如,如果您想將事件偵聽器添加到輸入中,您可以立即執行此操作,並且不需要調用form上的querySelector,這將會非常慢。當然,當插入真正的許多元素時(使用innerHTML),您根本不需要這樣做,因爲您會使用delegated events獲得真實的性能提升。

請注意,您還可以縮短方法#1與jQuery的oneliner:

var div, label, input; 
$(form).append(div=$("<div/>").append(input=$("<input/>"),label=$("<label/>"))); 

我的結論:

  • 爲了創建只有少數元素DOM方法是清潔劑。
  • 大多數情況下,html字符串更具可讀性。
  • 在標準情況下,兩者都不會更快 - 基準測試結果差別很大。

就個人而言,我不喜歡的幾個原因,這是在thesetwo答案和here概述以及以及(直接)innerHTML。另外,IE在表格上有一個bug(參見Can't set innerHTML on tbody in IE

1

一般來說,重複擊中DOM要比使用innerHTML替換大塊HTML要慢得多。我相信這有兩個原因。一個是迴流。瀏覽器必須重新計算各種元素的潛在佈局影響。其他的,我相信,有人糾正我,如果我錯了,是,有參與翻譯的東西在瀏覽器的後編譯執行環境會在哪裏渲染和佈局狀態被處理成一個對象一點的開銷,你可以在JavaScript中使用。由於DOM經常處於不斷變化的條件下,因此每次只需很少的機會來緩存任何類型的結果,可能在某種程度上即使您只是創建新元素而不添加它們(因爲您很可能想要預處理CSS規則,以及諸如瀏覽器由於文檔類型等原因而可能在事先通用環境中應用的「模式」)。

DOM方法允許你創建文檔片斷創建並添加HTML元素那些不影響實際的文檔佈局,它可以幫助您避免不必要的迴流。

但這裏的地方會很奇怪。

  • 將新的HTML與什麼也沒有一個節點 - 接近領帶什麼的innerHTML通常在很多(主要是舊的)瀏覽器

  • 更換一噸的HTML內容快得多 - 實際上,當性能不太接近調用時,DOM方法往往會取勝。

基本上,innerHTML,如果它很臭,往往會在拆卸過程中發生很大的掉期。 DOM方法在拆解時效果更好,但在創建新的HTML和直接注入時會更慢,而在完全沒有任何顯着差異的情況下無需替換任何東西。

實際上有混合方法在那裏,當你有需要,可以對性能做很奇妙的事情。我在一年前使用過一個,對於爲延遲加載網格交換大量HTML內容而不是僅使用innerHTML的響應時間改進留下了深刻的印象。我希望我能找到一個鏈接到誰的搞清楚了這一點,拼寫出來在網絡上值得信任的傢伙(作者,寫了很多的正則表達式的東西太多 - 不能谷歌我的生活)。

由於風格VS PERF的問題,我想你應該避免反覆調整實際的DOM節點結構,但在一個文檔片段預先構建HTML與使用innerHTML的是相當多的判斷的問題。我個人很喜歡innerHTML,因爲JS有很多強大的字符串方法,可以將數據快速轉換爲HTML準備好的字符串。例如:

var htmlStr = '<ul><li>' + arrayOfNames.join('</li><li>') + '</li></ul>'; 

單線程是UL,我可以直接分配給innerHTML。使用正確的數據結構和簡單的while循環來構建完整表格幾乎是一件容易的事情。現在,使用DOM API構建與arrayOfNames的長度相同的UL。我真的想不出有很多好的理由去做這件事。在HTML5規範最終被採納之前,innerHTML成爲了事實上的標準。它可能不適合DOM API的基於節點的htmlElement對象調整方法,但它功能強大,可幫助您保持代碼簡潔明瞭。然而,我不可能做的是使用innerHTML來編輯和替換現有的內容。在新的HTML中處理數據,構建和交換比參考舊的HTML更安全,然後開始解析屬性等的innerHTML字符串,等等。

您的主要性能問題可能應該是避免在DOM的「實時」部分剔除,但其餘的我會留給人們作爲樣式和測試HTML代碼的問題。然而,innerHTML已經並且多年來一直在HTML5工作草案中,並且在現代瀏覽器中它是非常一致的。在此之前的幾年裏它也是事實上的規格,並且作爲一個選項是完全可行的,因爲在Chrome是新的之前,國際海事組織,但這是一個辯論,主要是在這一點上完成。

+0

不需要。每個DOM操作後瀏覽器都不會重新排列/重新繪製。它只會在a)腳本運行後或b)需要訪問像offset和co之類的佈局屬性之前執行。 – Bergi 2012-07-19 10:31:48

+0

我不是故意給這個印象。 「DOM方法允許您構建文檔片段,並在不影響實際文檔佈局的情況下創建並追加HTML元素,這可以幫助您避免不必要的迴流。」但是,通常情況下,只要您以任何方式觸摸CSS或更改文檔中的HTML(請記住看起來不相關的屬性的CSS xpath屬性),就會重排。 – 2012-07-19 16:51:35