在本教程中,您将了解在 DOM 树中创建新元素时 innerHTML
与 createElement
之间的区别。
createElement 性能更好
假设您有一个 div
并且类名是 container 的元素:
<div class="container"></div>
您可以通过创建元素并使用 appendChild 向 div
元素添加新的子元素:
let div = document.querySelector('.container');
let p = document.createElement('p');
p.textContent = 'JS DOM';
div.appendChild(p);
您还可以像这样直接操作 HTML 元素的使用 innerHTML
:
let div = document.querySelector('.container');
div.innerHTML += '<p>JS DOM</p>';
当您想向元素添加属性时,使用 innerHTML
会使代码更少,更加简洁:
let div = document.querySelector('.container');
div.innerHTML += '<p class="note">JS DOM</p>';
但是,使用 innerHTML
会导致 Web 浏览器重新解析并重新创建 div 元素内的所有 DOM 节点。因此,它比创建一个新元素并追加到 div 的效率要低。
换句话说,创建一个新元素并将其追加到 DOM 树可提供比 innerHTML
更好的性能。
createElement 更安全
正如 innerHTML 教程中提到的,只有当数据来自受信任的来源(例如数据库)时才应该使用它。
如果将自己无法控制的内容赋值给元素的 innerHTML 属性,恶意代码可能会被注入并执行。
DocumentFragment 组合 DOM 节点
假设您有一个 HTML 列表,并且你需要迭代所有元素,下面的代码会导致每次迭代重新计算样式、绘制和布局,性能效率低下。
let div = document.querySelector('.container');
for (let i = 0; i < 1000; i++) {
let p = document.createElement('p');
p.textContent = `Paragraph ${i}`;
div.appendChild(p);
}
为了克服这个问题,您应该使用 DocumentFragment
来组成 DOM 节点并将其追加到 DOM 树:
let div = document.querySelector('.container');
// compose DOM nodes
let fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
let p = document.createElement('p');
p.textContent = `Paragraph ${i}`;
fragment.appendChild(p);
}
// append the fragment to the DOM tree
div.appendChild(fragment);
在此示例中,我们使用 DocumentFragment
对象组合 DOM 节点,并在最后将片段追加到活动 DOM 树中。
DocumentFragment 文档片段不会链接到活动 DOM 树,因此不会产生任何性能的损失。你可以查看 DocumentFragment
教程了解更多详细信息。