将元素添加为字符串与 createElement()

Posted

技术标签:

【中文标题】将元素添加为字符串与 createElement()【英文标题】:Adding elements as a string vs. createElement() 【发布时间】:2011-08-18 05:00:41 【问题描述】:

对于我想要完成的任务,我可以使用createElement()innerhtml 和一个字符串。

到底哪个更快?很长一段时间以来,我一直认为字符串比返回相同结果的内置函数要慢得多,但这是真的吗?

我问是因为我已经尝试过 createElement() 并且似乎必须添加到每个元素的所有属性都会减慢速度。不仅如此,它还占用更多空间。我有一个循环,它根据数组的长度从 1 无穷大开始,但最好在显示减速迹象之前添加多达 50 个左右的元素。在我希望创建的这 50 个左右的元素中,还有大约 10 个元素。因此,总的来说,它实际上创建了大约 500 个元素。

通过使用内置函数创建元素,我注意到速度比平时快了一点,并且由于我在重置该数组(数组是 5D 并且未在同一个脚本中设置)鬼混,我想在重新开始之前,要知道哪个是真正更好的,无论是速度还是更好的做法。

【问题讨论】:

也许你应该创建两个版本并测试哪个版本最快 我怀疑无论哪种方式都会有很大的性能差异。我建议选择最容易编码和维护的方法。我使用的一般经验法则是,对于较小的更改(更新文本、添加链接等)使用innerHTML,对于重大更改(将许多链接或组件添加到单个容器,或任何超过2 个节点深)使用createElement() 非常有趣的问题,我很想找到一些实际的基准。我已经看到 js-widgets 在加载时使用 json 数据而不是使用预加载(和隐藏)来水合相当大的嵌套 createElement 结构html模板直接复制。但即使这样也可能会在数百个项目的列表视图中丢失到 innerHTML 【参考方案1】:

此问题的性能差异因浏览器而异,并且(有时)在任何一种浏览器的不同版本之间存在差异,我已经看到一些不同的文章就这个问题提供了不同的建议。

根据我自己的经验,我只记得有一次我真的需要对一个大网页进行大量更改,特别是重建一个表格元素,该元素有数百甚至可能数千行,每行都有很多单元格,并且 我发现构建一个字符串变量,然后在最后设置一次 innerHTML 比尝试通过 DOM 函数执行它要快得多,很多但是,这是针对特定的 Intranet Web 应用程序,它保证 100% 的用户会使用 IE,因此我无需担心跨浏览器测试。

即使您决定走弦乐构建路线,对于如何加快速度也有不同的看法。我读过不止一篇文章比较了连续添加到字符串末尾(标准myString += 'something' + 'something else' 类型操作)与追加到数组变量末尾然后使用 Array.join() 创建一个大最后的字符串。同样,这对某些浏览器的某些版本产生了很大的影响,但在其他浏览器中没有什么不同或更糟。

【讨论】:

奇怪的是,这是最准确的答案,因为不同的浏览器似乎确实比另一种更快。 IE 显然可以更好地处理字符串,但与 innerHTML 相比,Google Chrome 处理 DOM 方法的速度非常快。【参考方案2】:

如果您有大量内容要附加到或填充现有元素,则innerHTML 是有意义的。

不久前,DOM 方法比分配给元素的 innerHTML 属性要慢得多,但最近它们非常快,而且由于所有必需的调用而变得不方便。但是您可以创建辅助函数来接受具有创建元素所需的所有信息的对象以减轻负担。

innerHTML 的使用有一些注意事项:

    很难在其他兄弟节点之间插入多个兄弟节点。为此,您最终将 HTML 插入到其他元素(例如 div)中,然后将创建的元素移动到 DOM 中。不幸的是,您不能为此使用 documentFragment,因此它需要遍历子节点 在表格上使用它可能会出现问题,IE 不喜欢修改 TD 以外的表格中各种元素的 innerHTML 浏览器生成不同的 HTML 作为 innerHTML 属性,因此使用它来序列化元素是有问题的 使用 innerHTML 属性可能会删除其他元素上的侦听器,即使它们没有被 innerHTML 修改

例如

<div id="div0">div0</div>

<!-- Button to add a click listener to above div -->
<button onclick="
  var el = document.getElementById('div0');
  el.onclick = function()alert(this.id);
">Add listener as property</button>

<!-- Button to modify the body's innerHTML -->
<button onclick="
  var body = document.getElementsByTagName('body')[0];
  body.innerHTML += '';
">Append to body.innerHTML</button>

您可以单击第一个按钮向 div0 添加一个单击侦听器,但是当您单击第二个按钮时(似乎什么都不做,但实际上重置了 innerHTML),侦听器被删除.

【讨论】:

【参考方案3】:

我猜你已经部分回答了你自己的问题。

除非您想使用 innerHTML 插入非常大的 html 块,否则速度不会受到真正的影响。使用 createElement 更“对 DOM 友好”,但有时你会得到更多代码行来进行小改动。

我个人使用innerHTML,或者任何jQuery 使用.html() 属性。但是当我必须使用循环来执行复杂的工作时,我会使用 create 元素。

最后一切都是一样的,只是性能差异并不重要。一旦浏览器重排文档,您就可以以同样的方式访问您的文档。

【讨论】:

有了jQuery就不需要使用html() -- elementX.append($('&lt;span&gt;this works as expected&lt;/span&gt;')).click(...) 这很有趣,我不知道你可以这么快地访问你的字符串。 我在几分钟前向 OP 添加了一些信息。我让它听起来有点像,但我在循环中添加的每个元素也包含大约 10 个元素,所以它实际上确实相当于一个大块。

以上是关于将元素添加为字符串与 createElement()的主要内容,如果未能解决你的问题,请参考以下文章

createElement() 与 innerHTML 啥时候使用?

DOM添加

如何在 JavaScript 中向 DOM 元素添加类?

如何在 Document.createElement() 中使用特殊字符 - VBA DOM XML

将jquery datepicker添加到使用document.createElement()创建的输入文本框中

js添加子元素 table tr td createElement