在DOM编程中,innerHTML和createElement都可以往页面中去追加元素,那么它们之间有什么区别?


在DOM编程中,innerHTML和createElement都可以往页面中去追加元素,那么它们之间有什么区别?

下面让我们来一步一步看

#1) createElement 性能更好

假如我们有一个div,然后需要往里插入元素

createElement

使用createElement来创建元素,然后使用appendChild来插入到页面中

1
2
3
4
5
6
7
8
9
<div class="container"></div>

<script>
let div = document.querySelector('.container');

let p = document.createElement('p');
p.textContent = 'JS DOM';
div.appendChild(p);
</script>

innerHTML

使用innerHTML来在div内追加元素

1
2
let div = document.querySelector('.container');
div.innerHTML += '<p>JS DOM</p>';

使用innerHTML来去创建元素,更简单、更简洁、更直观。

1
2
let div = document.querySelector('.container');
div.innerHTML += '<p class="note">JS DOM</p>';

但是,使用 innerHTML 会导致浏览器重新解析并重新创建 div 元素内的所有 DOM 节点。 因此,它比创建一个新元素并追加到 div 中效率低。 换句话说,创建一个新元素并将其追加到 DOM 树中比 innerHTML有着更好的性能。

#2) createElement 更安全

如果innerHTML的数据来自我们自己,那可以认为是安全的。

如果innerHTML的数据来自于用户,我们无法控制其是否安全,以及是否被注入了恶意代码。

#3) 使用 DocumentFragment DOM片段

假如我们有一个1000个列表的子元素需要插入到页面中,我们需要像下面一样去循环

1
2
3
4
5
6
7
8
9
10
11
<div class="container"></div>

<script>
let div = document.querySelector('.container');

for (let i = 0; i < 1000; i++) {
let p = document.createElement('p');
p.textContent = `段落 ${i}`;
div.appendChild(p);
}
</script>

但这会有个问题,每个元素被插入到div中都会重新计算样式、绘制和布局,损失性能。

为了解决这个问题,我们通常去使用DocumentFragment来收集所有DOM节点并一次插入到DOM中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="container"></div>

<script>
let div = document.querySelector('.container');

// 使用DocumentFragment
let fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
let p = document.createElement('p');
p.textContent = `段落 ${i}`;
fragment.appendChild(p);
}

// 将fragment插入到div
div.appendChild(fragment);
</script>

在上面代码中,我们先把生成的DOM先插入到DocumentFragment对象中,最后经DocumentFragment一次的插入到页面中。所以比每次插入更加高效。

使用innerHTML的话,语法会更简洁直观

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="container"></div>

<script>
let div = document.querySelector('.container');

// 使用DocumentFragment
let html = ''
for (let i = 0; i < 1000; i++) {
html += `<p>段落 ${i}</p>`;
}

div.innerHTML = html;
</script>

总结

createElement性能更好,更安全,插入多个元素需要使DocumentFragment
innerHTML使用更简单、更简洁、更直观,但安全性需要注意

面试中问到的innerHTML与createElement创建方式的区别:可以从innerHTML是采用字符串拼接还是数组形式拼接和其结构来说