www.webdeveloper.com
Results 1 to 11 of 11

Thread: Adding HTML: createElement vs. innerHTML

  1. #1
    Join Date
    Sep 2011
    Posts
    2

    Adding HTML: createElement vs. innerHTML

    What advantage does adding elements via document.createElement have over writing markup naturally with innerHTML?

    For example...
    Code:
    document.innerHTML = "<div id='myDiv' style="background: #000000;">This is a div</div>";
    versus...

    Code:
    var div = document.createElement('div');
    div.id = "myDiv";
    div.style.background = "#000000;"
    The latter method has much more overhead and is considerably more difficult to write with. However, there must be an advantage of some sort to doing it this way, but it's not exactly clear to me why...

    Can anyone explain the distinction? Thanks!

  2. #2
    Join Date
    Nov 2010
    Posts
    1,036
    they are the two worst-written pieces of sample code I think I have ever seen - both guaranteed never to do what they are supposed to be doing.

    If you want to compare, try this:

    Code:
    <div id="div3"></div>
    <div id="div2"></div>
    <script type="text/javascript">
    document.getElementById("div3").innerHTML = "This is a div";
    document.getElementById("div3").style.backgroundColor="#0000FF";
    
    
    div2=document.getElementById("div2")
    div = document.createElement('div');
    div.id = "myDiv";
    div.appendChild(document.createTextNode('This is another div'));
    div.style.backgroundColor = "#00FF00"
    div2.appendChild(div);
    </script>
    the web is full of debates about innerHTML vs createElement. Try googling "innerHTML vs createElement"

  3. #3
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,773
    I would vote for using innerHTML unless you are creating small DOM structures. Browsers are bred to parse HTML. It's what they do. Creating a complex and large DOM structure takes less time and less code when using innerHTML, plus you can leverage a template layer in a server side application to churn out the HTML.

    If you want to insert an element along side other child elements, then createElement is the way to go.

    Basically, if the DOM structure is expendable, use innerHTML. It's the "shot gun" approach.

    If you want to insert one element and not touch any of the other elements around it, use createElement and appendChild/insertBefore. This is the "surgical" approach.

    The one you use depends on the problem you're trying to solve. Both a sledge hammer (innerHTML) and a scalpel (createElement/appendChild) have their uses.

  4. #4
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Quote Originally Posted by toicontien View Post
    Both a sledge hammer (innerHTML) and a scalpel (createElement/appendChild) have their uses.
    Nice said Agree.

    I would add some thoughts:

    For a rough, quick solve, use innerHTML. It will work in, say, 90&#37; of the situations. If something fails, use DOM compliant methods instead.

    For instance, you all should know that, in IE, innerHTML should be used as a readonly method in case of several elements (TABLE, table's elements, and several few). See also:

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    There are rare cases, also, when innerHTML will not insert all the elements, nor all the attributes into the DOM tree. It is always to be tested, from case to case. But innerHTML has two advantages: it is relative quick to be written and read, and it is faster than DOM methods. But it is not a good vector to deliver/get serialized data (JSON, XML, and so on). And another disadvantage: the string returned on reading differs from browser to browser, thus you can not rely on a perfect copy of the syntax (double quotes, single quotes, lowercase, etc)

    Usually, innerHTML is a good tool to insert an AJAX responseText, when the response was created at a server-side level. But when working locally, maybe the DOM methods are better and more accurate.
    Last edited by Kor; 09-28-2011 at 07:31 AM.

  5. #5
    Join Date
    Jun 2009
    Location
    Miami
    Posts
    118
    Years ago I wrote an HTML markup parsing JS function that builds DOM elements and their attributes on a DocumentFragment node which can then be appended as a child dynamically to the existing document. At the time, the innerHTML property was implemented only by IE as I recall and not at all standard. You probably will have problems when the markup you wish to attach includes script and style elements in which case you want to use DOM methods (which also show browser-dependence). Because I was discouraged from using innerHTML, I prefer DOM methods now and force myself to make them work.

    In fact, I am back in this forum after a long absence in order to solve a problem with a tree of nodes created by DOM methods not working now.

  6. #6
    Join Date
    Jan 2007
    Location
    Wisconsin
    Posts
    2,120
    innerHTML is almost always far faster and easier to work with. But, it forces you to relocate the created nodes if you need to refer to them again. And it becomes much more difficult to refer to a "fleeting" object in an event handler without a node reference.

    I usually use a combination:

    PHP Code:
    // firstly, we're almost always working from within a function:
    function doSomething() {
      
    // firstly, unless we're creating nodes it the context of other objects,
      // there's generally no reason to be creating nodes dynamically.
      // so, here's our context. we've been doing stuff with this object:
      
    var = new FancyObject();
      
    o.doStuff();
      
    o.doMoreStuff();
      
    o.etc();

      
    // and now we need to put something on the page to work with the object:
      
    var document.createElement('div');

      
    // the preliminary/leading HTML is usually easiest to write directly:
      
    n.innerHTML "<h5>Edit</h5> FancyObject: ";

      
    // it's often easiest for the objects we're working with to be able to 
      // build their own node structures. This also allows our object to track and
      // update any nodes that represent it as its data changes.
      
    n.appendChild(o.getNode());

      
    // now let's put a button on the page to do something to the node
      
    var document.createElement('input');
      
    b.type 'button'
      
    b.value 'Click me';
      
    b.onclick = function() {
        
    // we can refer directly to object o here. and by doing so, we don't have
        // to create any sort of cache to hold onto object o. nor do we have to
        // know where it is (if anywhere) in some complex object hierarchy. it's
        // right here. and if nowhere else, the reference to it here keeps it alive:
        
    o.doSomethingReallyCool();
      }

      
    n.appendChild(b);


    A silly, simple example of course. But the idea is that you can more easily attach object and function references to nodes as they're created. And in some cases, where you may be tempted to just refer to objects by a location in some global object cache array, you'll find it to be far more complicated, messy, and memory-leaky to build HTML that works with your global object cache.

    If you have a big hierarchy of objects--or even a little one, several objects deep--each of which needs to generate nodes that can interact with the originating object, it's much easier to include object references on the nodes, rather than indexes to a global object cache. And then, of course, if another part of the application needs to play with the resulting node, you don't have to generate an ID and then fetch the node you just created, because you've already got a reference to it!

    ... that make sense at all?
    Last edited by svidgen; 09-29-2011 at 09:26 AM. Reason: forgot an appendChild()
    Jon Wire

    thepointless.com | rounded corner generator

    I agree with Apple. Flash is just terrible.

    Use CODE tags!

  7. #7
    Join Date
    Dec 2008
    Posts
    488
    Quote Originally Posted by svidgen View Post
    innerHTML is almost always far faster and easier to work with.
    I think it's important to make it clear that by "faster" you mean "faster to program". In the case of many iterations of a loop, createElement() is faster for the browser to execute. .innerHTML causes the browser to run a lot of extra code and creates more memory overhead.

    createElement() allows you to create precise elements with only the attributes you need, and also inserts them correctly into the DOM. You can easily work with createElement() in loops where you need to create several elements by using anonymous function execution:
    Code:
    (function(arg1, arg2) {
        ...statements...;
    })(true, 3);

  8. #8
    Join Date
    Jan 2007
    Location
    Wisconsin
    Posts
    2,120
    Quote Originally Posted by jamesbcox1980 View Post
    I think it's important to make it clear that by "faster" you mean "faster to program". In the case of many iterations of a loop, createElement() is faster for the browser to execute. .innerHTML causes the browser to run a lot of extra code and creates more memory overhead.
    Actually no. I mean faster all around: both to program and to render. This may vary by browser; but the last benchmarks I saw on the matter showed that innerHTML is significantly faster executing and rendering than creating "proper" DOM nodes.
    Jon Wire

    thepointless.com | rounded corner generator

    I agree with Apple. Flash is just terrible.

    Use CODE tags!

  9. #9
    Join Date
    Jan 2007
    Location
    Wisconsin
    Posts
    2,120
    Here's the benchmark, actually. I ran the tests myself a few months ago and verified that innerHTML is faster. Having run them just now, I see that on my current configuration (latest Chrome update on OS X, 2.4Ghz duo), the results are all equivalent--possibly in part because they're all so fast on modern hardware that the differences are negligible.

    However, running the same tests on my quad-core windows PC with the latest firefox build shows that the innerHTML operations run between 3 and 4 times faster than the corresponding DOM methods.

    In IE 8 on the same machine, the innerHTML methods are 6 to 8 times faster.

    ADDENDUM: I forgot the link: http://www.quirksmode.org/dom/innerhtml.html
    You can run each benchmark by clicking the Test Now link under each method heading along the left.

    ADDENDUM 2: Safari is the only browser I've tested wherein the DOM methods are faster (about 2x so). But, given market share, using innerHTML for complex structurs definitely outweighs the slight advantage Safari gives to the DOM operations.
    Last edited by svidgen; 09-29-2011 at 11:58 AM.
    Jon Wire

    thepointless.com | rounded corner generator

    I agree with Apple. Flash is just terrible.

    Use CODE tags!

  10. #10
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,773
    You both are partially right. Setting the innerHTML on a DOM node causes a redraw. If the page is very big and the design very complex, it might be less work for the browser to use createElement, however in that case I'd recommend concatenating HTML inside the loop, and once the loop has finished inject it once, causing one redraw.

  11. #11
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by jamesbcox1980 View Post
    In the case of many iterations of a loop, createElement() is faster for the browser to execute. .innerHTML causes the browser to run a lot of extra code and creates more memory overhead.

    createElement() allows you to create precise elements with only the attributes you need, and also inserts them correctly into the DOM.
    that sounds good, but remember that the main function of a browser is to turn HTML into a dom tree. consider that every decent web programmer knows offhand that using the dom is slower than running pure js. since innerHTML use but one js line and no dom interaction overhead for sub-tags, it's going to be faster than create Element().


    it used to be hard to grab tags from a hunk of html, and that was never a problem with createElement because every single dang tags needs it's own variable at some point. using Element.querySelectorAll(strCSS) is easier than vars because you can re-cast it into different shapes so easily to get at whatever node you need to bind events to or whatever you needed object access to the node to do...

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles