Appending HTML string to the DOM
Solution 1:
Use insertAdjacentHTML
which is supported in all current browsers:
div.insertAdjacentHTML( 'beforeend', str );
The position parameter beforeend
will add inside the element, after its last child.
Live demo: http://jsfiddle.net/euQ5n/
Solution 2:
Performance
AppendChild
(E) is more than 2x faster than other solutions on chrome and safari, insertAdjacentHTML
(F) is fastest on firefox. The innerHTML=
(B) (do not confuse with +=
(A)) is second fast solution on all browsers and it is much more handy than E and F.
Details
Set up environment (2019.07.10) MacOs High Sierra 10.13.4 on Chrome 75.0.3770 (64-bit), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-bit)
- on Chrome E (140k operations per second) is fastest, B (47k) and F (46k) are second, A (332) is slowest
- on firefox F (94k) is fastest, then B(80k), D (73k), E(64k), C (21k) slowest is A(466)
- on Safari E(207k) is fastest, then B(89k), F(88k), D(83k), C (25k), slowest is A(509)
You can replay test in your machine here
function A() {
container.innerHTML += '<p>A: Just some <span>text</span> here</p>';
}
function B() {
container.innerHTML = '<p>B: Just some <span>text</span> here</p>';
}
function C() {
$('#container').append('<p>C: Just some <span>text</span> here</p>');
}
function D() {
var p = document.createElement("p");
p.innerHTML = 'D: Just some <span>text</span> here';
container.appendChild(p);
}
function E() {
var p = document.createElement("p");
var s = document.createElement("span");
s.appendChild( document.createTextNode("text ") );
p.appendChild( document.createTextNode("E: Just some ") );
p.appendChild( s );
p.appendChild( document.createTextNode(" here") );
container.appendChild(p);
}
function F() {
container.insertAdjacentHTML('beforeend', '<p>F: Just some <span>text</span> here</p>');
}
A();
B();
C();
D();
E();
F();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This snippet only for show code used in test (in jsperf.com) - it not perform test itself.
<div id="container"></div>
Solution 3:
Is this acceptable?
var child = document.createElement('div');
child.innerHTML = str;
child = child.firstChild;
document.getElementById('test').appendChild(child);
jsFiddle.
But, Neil's answer is a better solution.
Solution 4:
The idea is to use innerHTML
on an intermediary element and then move all of its child nodes to where you really want them via appendChild
.
var target = document.getElementById('test');
var str = '<p>Just some <span>text</span> here</p>';
var temp = document.createElement('div');
temp.innerHTML = str;
while (temp.firstChild) {
target.appendChild(temp.firstChild);
}
This avoids wiping out any event handlers on div#test
but still allows you to append a string of HTML.
Solution 5:
The right way is using insertAdjacentHTML
. In Firefox earlier than 8, you can fall back to using Range.createContextualFragment
if your str
contains no script
tags.
If your str
contains script
tags, you need to remove script
elements from the fragment returned by createContextualFragment
before inserting the fragment. Otherwise, the scripts will run. (insertAdjacentHTML
marks scripts unexecutable.)