什么是更好的,通过DOM函数追加新元素,或附加HTML标签的字符串?

Chr*_*ski 21 javascript dom appendchild

我已经看到了一些向DOM添加元素的不同方法.例如,最普遍的似乎也是

document.getElementById('foo').innerHTML ='<p>Here is a brand new paragraph!</p>';
Run Code Online (Sandbox Code Playgroud)

要么

newElement = document.createElement('p');
elementText = document.createTextNode('Here is a brand new parahraph!');
newElement.appendChild(elementText);
document.getElementById('foo').appendChild(newElement);
Run Code Online (Sandbox Code Playgroud)

但我不确定做任何一个的好处.是否有一个经验法则,关于什么时候应该完成另一个,或者其中一个是否完全错了?

Way*_*ett 20

一些说明:

  • innerHTML在IE中使用速度更快,但在chrome + firefox中使用速度更慢.这是一个基准测试,显示了一组不断变化的<div>s + <p>s; 这是一个基准,显示了这个常数,简单<table>.

  • 另一方面,DOM方法是传统标准 - innerHTML在HTML5中标准化 - 并允许您保留对新创建元素的引用,以便您以后可以修改它们.

  • 因为innerHTML快速(足够),简洁且易于使用,所以在任何情况下都倾向于使用它.但请注意,使用从文档中innerHTML分离所有现有DOM节点.以下是您可以在此页面上测试的示例.

    首先,让我们创建一个函数,让我们测试节点是否在页面上:

    function contains(parent, descendant) {
        return Boolean(parent.compareDocumentPosition(descendant) & 16);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    true如果parent包含,则返回descendant.像这样测试:

    var p = document.getElementById("portalLink")
    console.log(contains(document, p)); // true
    document.body.innerHTML += "<p>It's clobberin' time!</p>";
    console.log(contains(document, p)); // false
    p = document.getElementById("portalLink")
    console.log(contains(document, p)); // true
    
    Run Code Online (Sandbox Code Playgroud)

    这将打印:

    true
    false
    true
    
    Run Code Online (Sandbox Code Playgroud)

    它可能看起来不像我们的使用innerHTML应该影响我们对portalLink元素的引用,但确实如此.需要再次检索才能正常使用.


Jon*_*Jon 5

有许多不同之处:

  1. innerHTML仅由W3C标准化为HTML 5; 虽然它现在已成为所有流行浏览器的事实上的标准,但从技术上来说,它是HTML 4中的供应商扩展,标准粘贴的开发人员永远不会被捕获.另一方面,所有浏览器都支持它更加方便和实用.
  2. innerHTML 替换元素的当前内容(它不允许您修改它).但同样,如果你不介意这个限制,你会获得方便.
  3. innerHTML 已被测量为更快(不可否认,该测试涉及今天未广泛使用的旧版浏览器).
  4. innerHTML如果设置为用户提供的尚未正确编码的值(例如el.innerHTML = '<script>...'),则可能表示安全风险(XSS ).

基于以上所述,似乎一个实际的结论可能是:

  • 如果您不介意innerHTML有点限制(仅根据目标元素完全替换DOM子树)并且您不会通过注入用户提供的内容来冒漏洞,请使用它.否则,请使用DOM.