【问题标题】:Which method is better/ faster for performance - createElement or innerHTML? [duplicate]哪种方法更好/更快的性能 - createElement 或 innerHTML? [复制]
【发布时间】:2017-06-27 09:21:24
【问题描述】:

我正在制作带有几个子元素的 div,如下所示:

<div class="item" data-id="28">
    <div class="action-btns">
        <button class="add"></button>
        <button class="rmv"></button>
    </div>
    <div class="info">
        <h3>Title here</h3>
        <span>caption here</span>
    </div>
</div>

我在点击时为这两个按钮提供功能。我想知道创建这些项目的哪种方法更好 - createElement innerHTML

createElement 而言,我喜欢它,因为我可以在元素内创建按钮时绑定 onclick,然后附加它。我还想知道将这个“项目”附加到父 div 是否比更新 innerHTML +=“某物”更快/更好;

innerHTML 而言,要编写的代码行数更少,但我也必须在按钮内编写 onclick="myFunction()" 而不是动态添加它。

请不要使用 jQuery 或任何纯 Js。感谢您的宝贵时间:)

【问题讨论】:

标签: javascript html


【解决方案1】:

https://jsperf.com/innerhtml-vs-createelement-test(注意不是我写的)

使用 createElement 时,chrome 中的结果大约慢了 60%。根据(@Sagar V 和@Hajji Tarik)的回答,考虑的不仅仅是速度。

【讨论】:

  • 所以根据这个使用innerHTML会更胖吗?
  • InnerHtml 更快,因为您将字符串放入 innerHTML = ... 然后浏览器会将其翻译为 html,但 createElement 创建一个您可以链接事件的 html 节点
  • 从纯粹的速度角度。是的。在 Edge 中也有类似的结果。
  • 如果你正在对这些元素进行处理,我建议使用 createElement
  • 我很困惑。我还必须考虑动画。我正在动态加载元素,并希望它们在加载时具有动画效果。因此,每当我使用 innerHTML 时,它都会重新设置所有元素。所以在这种情况下 createElement 更好,因为我可以绑定函数保持引用并只动画最后加载的元素?
【解决方案2】:

除了安全性之外,使用 createElement 而不是修改 innerHTML(而不是仅仅丢弃已经存在的内容并替换它)还有几个优点,就像 Pekka 已经提到的那样:

在附加元素时保留对 DOM 元素的现有引用

当您附加到(或以其他方式修改)innerHTML 时,该元素内的所有 DOM 节点都必须重新解析和重新创建。如果您保存了对节点的任何引用,它们将基本上是无用的,因为它们不再显示了。

保留附加到任何 DOM 元素的事件处理程序

这实际上只是最后一种情况的特例(尽管很常见)。设置 innerHTML 不会自动将事件处理程序重新附加到它创建的新元素,因此您必须自己跟踪它们并手动添加它们。在某些情况下,事件委托可以消除这个问题。

在某些情况下可能更简单/更快

如果您要进行大量添加,您肯定不想一直重置 innerHTML,因为虽然简单更改更快,但重复重新解析和创建元素会更慢。解决这个问题的方法是在一个字符串中构建 HTML,并在完成后设置一次 innerHTML。根据具体情况,字符串操作可能比创建元素并附加它们要慢。

此外,字符串操作代码可能更复杂(特别是如果您希望它是安全的)。

这是我有时使用的一个函数,它使 createElement 的使用更加方便。

function isArray(a) {
    return Object.prototype.toString.call(a) === "[object Array]";
}

function make(desc) {
    if (!isArray(desc)) {
        return make.call(this, Array.prototype.slice.call(arguments));
    }

    var name = desc[0];
    var attributes = desc[1];

    var el = document.createElement(name);

    var start = 1;
    if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) {
        for (var attr in attributes) {
            el[attr] = attributes[attr];
        }
        start = 2;
    }

    for (var i = start; i < desc.length; i++) {
        if (isArray(desc[i])) {
            el.appendChild(make(desc[i]));
        }
        else {
            el.appendChild(document.createTextNode(desc[i]));
        }
    }

    return el;
}

如果你这样称呼它:

make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);

你会得到这个 HTML 的等价物:

<p>Here is a <a href="http://www.google.com/">link</a>.</p>

@Matthew Crumley的答案

【讨论】:

  • @Matthew Crumley 的答案
  • @RomanPerekhrest 哦。我搜索了这个,但它没有显示。 (问题/答案)。我认为问题的措辞不同,以至于找不到它。
【解决方案3】:

innerHTML 只需输入纯文本即可。而createElement 创建元素对象并添加到父对象。 由于浏览器将纯文本中的标签转换为 HTML 元素,因此它被转换为标签。不推荐。

createElement 是推荐的方法

【讨论】:

  • 谢谢 :) 您是否知道更新父级的 innerHTML 是否会刷新所有内容,而 appendChild 仅是最后一个元素?至少在我看来是这样。
  • 但在某些旧浏览器中可能会出现异常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2012-02-08
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多