2010-08-10 87 views
3

我有以下代碼:什麼是更好的DOM操作 - DOM API或innerHTML?

tr = document.createElement("tr"); 
root.appendChild(tr); 
td = document.createElement("td"); 
td.appendChild(document.createTextNode("some value")); 
tr.appendChild(td); 

嗯,這個代碼是一樣的

root.innerHTML = "<tr><td>some value</td></tr>"; 

第一個版本可能是一個更好的路要走,因爲瀏覽器並沒有呈現一個字符串。但它太長了。特別是對於更大的結構,這種實現變得非常難以閱讀。所以我覺得有一個更好的方式來寫這個(沒有任何JavaScript庫)。你將如何實現這個,以便代碼更具可讀性? (現在我正在將代碼與評論分開。)

+3

實際上,innerHTML比創建DOM節點要快得多。請參閱http://www.quirksmode.org/dom/innerhtml.html。 – kennytm 2010-08-10 06:34:41

+0

@KennyTM:那些測試結果已經兩年了。 – Gumbo 2010-08-10 06:42:30

+1

@Gumbo:innerHTML的仍然是最快的蛤蚧(火狐)或Presto(Opera)的今天,但對於WebKit的(Chrome和Safari瀏覽器)中的「表法」比較快。像OP所做的那樣創建DOM節點對所有這4種瀏覽器來說都是最慢的。 – kennytm 2010-08-10 06:57:25

回答

5

你總是可以寫周圍的笨重的DOM包裝功能API使代碼更具可讀性。我通常使用類似:

function newElement (type,attr,children) { 
    var el = document.createElement(type); 
    for (var n in attr) { 
     if (n == 'style') { 
      setStyle(el,attr[n]); /* implementation of this function 
            * left as exercise for the reader 
            */ 
     } 
     else { 
      el[n] = attr[n]; 
     } 
    } 
    if (children) { 
     for (var i=0; i<children.length; i++) { 
      el.appendChild(children[i]); 
     } 
    } 
} 
function newText (text) { 
    document.createTextNode(text); 
} 

然後你可以寫更多的聲明性代碼:

var tr = newElement('tr',{},[ 
    newElement('td',{},[ 
     newText('some value') 
    ]) 
]); 

只要記住CSS和JavaScript之間的差異:

var div = newElement('div',{ 
    className:'foo', 
    style:{ 
     marginLeft:'10px' 
    } 
},[ 
    newText('notice we use "className" instead of class" '+ 
      'and "marginLeft" instead of "margin-left"') 
]); 
0

innerHTML原本是IE的東西,我相信。

我還以爲你設置它,因爲它不是一個方法,讓第二個例子是

root.innerHTML = "<tr><td>some value</td></tr>"; 

但是,爲了回答你的問題,innerHTML更方便,但它經常被認爲是慢。然而,KennyTM在評論中說,它是much faster

必須決定是否性能權衡,這可能可以忽略不計,值得做它的DOM API方式或innerHTML的方式。

0

使用jQuery http://jquery.com/

$('#root tbody').append('<td><td>some value</td></td>'); 

它甚至會使用正確的DOM方法。

編輯:從jQuery文檔:

jQuery是一個快速,簡潔的 JavaScript庫,簡化 HTML文檔遍歷,事件 處理,動畫和Ajax 交互快速網絡 發展。 jQuery旨在將 更改爲您編寫 JavaScript的方式。

**編輯:**另外,我提出上述多一點HTML符合的@koby所述樣品;

+4

「使用jQuery」來回答有關未標記jQuery的JavaScript的問題通常會被忽略。然而,從我這裏沒有downvote ...讀[Bobince的](http://stackoverflow.com/users/18936/bobince)[愉快的文章](http://www.doxdesk.com/updates/2009.html):) – alex 2010-08-10 06:43:56

+0

+1因爲jquery只是簡單的方法來做到這一點 – 2010-08-10 06:50:18

+3

@June R是否值得包含一個24kB庫來保存少量的字符?什麼是錯的'root.innerHTML = 「​​一些價值」;'? – alex 2010-08-10 06:52:55

0

我會重新排序),以使其更易於閱讀

var d = document; 
td = d.createElement("td"); 
tr = d.createElement("tr"); 
td.appendChild(d.createTextNode("some value")); 
tr.appendChild(td); 
root.appendChild(tr); 
2

innerHTMLdefinitely比DOM更快(請參閱討論部分)。前一段時間,我碰到一個方式來方便編寫大型HTML結構與innerHTML來了,這是一個好一點的是字符串連接,也不必寫大的結構:

var html = [ 
    '<ul class="myclass">', 
     '<li class="item">item1</li>', 
     '<li class="item">item2</li>', 
     '<li class="item">item3</li>', 
     '<li class="item">item4</li>', 
     '<li class="item">item5</li>', 
    '</ul>' 
].join(""); 

root.innerHTML =html; 
+1

您需要設置屬性; 'innerHTML'是[不是方法](http://jsbin.com/ususi3/)。 – alex 2010-08-10 06:45:59

+1

@alex非常感謝,這是一個錯字:D – naikus 2010-08-10 07:01:22

1

正如我所提到的在評論中,innerHTML實際上比創建DOM節點更快,但它是非結構化的。

不是創建DOM節點更快的方法,但依然層次分明,是使用the DOM 2 table methods

var tr = root.insertRow(-1); 
var td = tr.insertCell(0); 
var txt = document.createTextNode("some value"); 
td.appendChild(txt); 
// or simply: td.innerHTML = "some value"; 
0

我寫了一些測試,我自己,比較的innerHTML和DOM API。 DOM API絕對更快。

下面是結果(我已在Firefix 3.6.8和Chrome 5.0.375.125測試測試): http://yilmazhuseyindevelopment.appspot.com/ois/images/ahh5aWxtYXpodXNleWluZGV2ZWxvcG1lbnRyEQsSCUltYWdlRGF0YRiptwUM

在第一測試中,我使用DOM API添加一個textnode到頁面的主體1000倍和innerHTML。

在第二個試驗我創建與DOM API和內部HTML的表。這裏是我的測試的實際代碼:

<html> 
    <head> 
     <script type="text/javascript"> 
     window.onload = function(){ 
      var body = document.getElementsByTagName("body")[0]; 
      var text,table,tr,td; 
      var count = 1000; 
      console.time("DOM"); 
      for(var i = 0 ; i<count ; i++){ 
        text = document.createTextNode("text"); 
        body.appendChild(text); 
        body.removeChild(text) 
      } 
      console.timeEnd("DOM"); 
      console.time("innerHTML"); 
      for(var i = 0 ; i<count ; i++){ 
       body.innerHTML = "text"; 
       body.innerHTML = ""; 
      } 
      console.timeEnd("innerHTML"); 
      //table structure 
      console.time("DOM2"); 
      for(var i = 0 ; i<count ; i++){ 
        table = document.createElement("table"); 
        tr = document.createElement("tr"); 
        td = document.createElement("td"); 
        text = document.createTextNode("text"); 
        table.appendChild(tr); 
        tr.appendChild(td); 
        td.appendChild(text); 
        body.appendChild(table); 
        body.removeChild(table); 
      } 
      console.timeEnd("DOM2"); 
      console.time("innerHTML2"); 
      for(var i = 0 ; i<count ; i++){ 
       body.innerHTML = "<table><tr><td>text</td></tr></table>"; 
       body.innerHTML = ""; 
      } 
      console.timeEnd("innerHTML2"); 
     } 
     </script> 
    </head> 

    <body/> 
</html> 

我想這意味着現代瀏覽器的DOM API更好(性能明智)。

0

你嘗試使用JavaScript模板引擎?

它們一般由innerHTML注入HTML字符串,並且比在兩個桌面DOM操作和同時保持視圖和邏輯之間的分離移動的方式更快。

我們使用PURE這完全分開的HTML標記和JavaScript邏輯。設計師和開發人員可以在相同的資源上一起工作。

如果你不喜歡它,你可以,可能更符合你的口味在網絡上找到很多其他人。

+0

不幸的是,我不能使用這個我自己寫一個工具。所以我真的不知道我會得到什麼樣的結構。由於我的應用程序是一個實用程序,我不想添加任何依賴項到我的代碼。我決定去純js。但模板引擎看起來很有前景,我可以在設置頁面時使用它們。感謝您的建議 – yilmazhuseyin 2010-08-10 07:46:56

+0

在小例子中測量原始速度非常困難。許多參數使得它很難(測量時JavaScript正在運行,瀏覽器版本和怪癖取決於內容的類型......)。我們使用DOM開始我們的網絡應用程序,因爲它更加優雅,但是當頁面開始擁擠時,對於高效環境來說太慢了,我們使用了模板引擎。我認爲innerHTML注入與從Web服務器接收HTML的瀏覽器並不是非常不同的邏輯。 – Mic 2010-08-10 08:33:04

1

嘿,我來晚了就這一個遊戲,但希望添加此信息對您所有。 在一些移動瀏覽器開發過程中,這個問題出現在我的面前,我想親眼看看哪一天更好。

在我的Android手機這裏的一些有趣的結果:

 
     DOM: 614/25 
innerHTML: 697/542 
     DOM: 546/18 
innerHTML: 639/552 
     DOM: 604/12 
innerHTML: 641/534 
     DOM: 619/11 
innerHTML: 643/554 
     DOM: 618/13 
innerHTML: 655/600 

第一個數字是增加2700種li元素的實際執行。 而且,更有趣是第二個數字,這是需要多長時間的使用olinnerHTML = '';

DOM vs innerHTML自己試着衝出這些結果。