2010-08-10 48 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自己试着冲出这些结果。