5

I'm making divs with several sub elements something like this:

<div class="item" data-id="28">
    <div class="action-btns">
        <button class="add"></button>
        <button class="rmv"></button>
    </div>
    <div class="info">
        <h3>Title here</h3>
        <span>caption here</span>
    </div>
</div>

And im giving functions to those two buttons on click. I'm wondering which method of creating these items is better - createElement or innerHTML?

As far as createElement goes i like it because i can bind the onclick while creating the button inside the element and then append it. Also im wondering if appending this "item" to the parent div is faster / better than updating innerHTML += "something";

As far as innerHTML goes there are fewer lines of code to write, but also i have to either write the onclick="myFunction()" inside the buttons instead of adding it dynamically.

Please no jQuery or anyting but pure Js. Thanks for your time :)

3 Answers3

3

https://jsperf.com/innerhtml-vs-createelement-test (Note i did not write this)

Results in chrome is about 60% ish percent slower using createElement. As per (@Sagar V and @Hajji Tarik) answer consider more then just speed.

Andrew Monks
  • 656
  • 4
  • 11
  • so according to this it is much fatser to use innerHTML? –  Feb 09 '17 at 11:37
  • 1
    InnerHtml is faster because you put a string in innerHTML = ... then the browser will translate it on html, but the createElement creates a html node that you can link events – Hajji Tarik Feb 09 '17 at 11:39
  • from a pure speed perspective. yes. Similar results in Edge also. – Andrew Monks Feb 09 '17 at 11:39
  • I recommend the use of createElement if you are doing treatments on these elements – Hajji Tarik Feb 09 '17 at 11:40
  • I'm confused. i also have to think about animations. I'm dynamically loading in elements and want them to have an animation when they load in. So whenever i used innerHTML it reanimated all of them. So in this case createElement is better since i can bind functions keep references and animate only the last loaded in elements? –  Feb 09 '17 at 11:41
  • Preserves event handlers attached to any DOM elements This is really just a special case (although common) of the last one. Setting innerHTML will not automatically reattach event handlers to the new elements it creates, so you would have to keep track of them yourself and add them manually. Event delegation can eliminate this problem in some cases. – Hajji Tarik Feb 09 '17 at 11:43
  • I think we would need more code to get a grasp of what you are doing to make more informed advice. – Andrew Monks Feb 09 '17 at 11:48
1

innerHTML just put the plain text. Whereas createElement creates the element object and adds to Parent. since browser convert tags in plain text to HTML element, it is converted to tags. It is not recommended.

createElement is the recommended method

Sagar V
  • 12,158
  • 7
  • 41
  • 68
  • Thanks :) do you happen to know if updating innerHTML of a parent refreshes everything while appendChild only the last element? At least it seem so to me. –  Feb 09 '17 at 11:31
  • But it may misbehave in some old browsers – Sagar V Feb 09 '17 at 11:32
1

There are several advantages to using createElement instead of modifying innerHTML (as opposed to just throwing away what's already there and replacing it) besides safety, like Pekka already mentioned:

Preserves existing references to DOM elements when appending elements

When you append to (or otherwise modify) innerHTML, all the DOM nodes inside that element have to be re-parsed and recreated. If you saved any references to nodes, they will be essentially useless, because they aren't the ones that show up anymore.

Preserves event handlers attached to any DOM elements

This is really just a special case (although common) of the last one. Setting innerHTML will not automatically reattach event handlers to the new elements it creates, so you would have to keep track of them yourself and add them manually. Event delegation can eliminate this problem in some cases.

Could be simpler/faster in some cases

If you are doing lots of additions, you definitely don't want to keep resetting innerHTML because, although faster for simple changes, repeatedly re-parsing and creating elements would be slower. The way to get around that is to build up the HTML in a string and set innerHTML once when you are done. Depending on the situation, the string manipulation could be slower than just creating elements and appending them.

Additionally, the string manipulation code may be more complicated (especially if you want it to be safe).

Here's a function I use sometimes that make it more convenient to use createElement.

function isArray(a) {
    return Object.prototype.toString.call(a) === "[object Array]";
}

function make(desc) {
    if (!isArray(desc)) {
        return make.call(this, Array.prototype.slice.call(arguments));
    }

    var name = desc[0];
    var attributes = desc[1];

    var el = document.createElement(name);

    var start = 1;
    if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) {
        for (var attr in attributes) {
            el[attr] = attributes[attr];
        }
        start = 2;
    }

    for (var i = start; i < desc.length; i++) {
        if (isArray(desc[i])) {
            el.appendChild(make(desc[i]));
        }
        else {
            el.appendChild(document.createTextNode(desc[i]));
        }
    }

    return el;
}

If you call it like this:

make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);

you get the equivalent of this HTML:

<p>Here is a <a href="http://www.google.com/">link</a>.</p>

The answer of @Matthew Crumley

Community
  • 1
  • 1
Hajji Tarik
  • 1,072
  • 7
  • 23