Dirk J. Faber
Dirk J. Faber

Reputation: 4701

'appending' in Javascript

I am trying to learn JS without the use of a framework. Just a little doubt with the following:

<div class="js-button"></div>

In jQuery I can create a submit button with:

$("<button type='submit'>Save</button>").appendTo($(".js-button"));

In plain JS I could do:

document.querySelector(".js-button").innerHTML += "<button type='submit'>Save</button>";

This is exactly the same, right? Are there other ways to do this? If you happen to make the mistake of writing = istead of += you can expect big problems which I try to avoid.

Upvotes: 4

Views: 885

Answers (2)

Get Off My Lawn
Get Off My Lawn

Reputation: 36351

I would like to just demonstrate the differences between using += with innerHTML, and = with innerHTML, and to answer the question:

If you happen to make the mistake of writing = instead of += you can expect big problems which I try to avoid.

innerHTML +=

When using += with innerHTML and appending 2000 items to a div, it takes about 4 seconds to render.

let div = document.querySelector('div')
console.time('append innerHTML')
for(let i = 0; i < 2000; i++){
  div.innerHTML += '<p>Hello</p>'
}

console.timeEnd('append innerHTML')
<div></div>

innerHTML =

When building a string and using innerHTML = instead, we can do more than double the amount of work in 75+% less time by building the string first then assigning it to innerHTML.

Here we used 10,000 elements instead of 2,000 elements (as seen above), and we also notice a huge speed improvement, a nearly instant render.

let div = document.querySelector('div')
console.time('append str')
let str = ''
for(let i = 0; i < 10000; i++){
  str += '<p>Hello</p>'
}

div.innerHTML = str
console.timeEnd('append str')
<div></div>

The reason the second example is faster, is because it only has to update the DOM one time instead of 2,000 or 10,000 times. Each update cause delay, and as the dom grows, so does the delay.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1075427

This is exactly the same, right?

No, not at all, though it's easy to see why you'd think that. It's almost never correct to use += with innerHTML. Doing so forces the browser to:

  • Spin through the element's contents building an HTML string
  • Append your string to that string
  • Destroy all of the contents of the element
  • Parse the string to build new contents, putting them in the element

...which aside from being a fair bit of unnecessary work also loses event handlers, the checked state of checkboxes/radio buttons, the selected options in select elements, etc.

Instead, use insertAdjacentHTML or createElement/createTextNode and appendChild. See the DOM on MDN. In that specific example:

document.querySelector(".js-button").insertAdjacentHTML(
    "beforeend",
    "<button type='submit'>Save</button>"
);
<div class="js-button"></div>

Upvotes: 6

Related Questions