2

I ran into a bit of code that I found interesting, and I am not sure why the coding pattern is used. Perhaps someone could enlighten me?

In the example bellow, an Array and join() is used to create a string of html then inserted into a DIV-element with innerHTML.

var div = document.createElement('div');
div.innerHTML = [
   '<div id="view">',
     '<button class="cancel">cancel</button>',
     '<ul id="presets"></ul>',
   '</div>'
 ].join('');
document.body.appendChild(div);

Why would one do this? Why not make a String as shown bellow.

var div = document.createElement('div');
div.innerHTML =
   '<div id="view">' +
     '<button class="cancel">cancel</button>' +
     '<ul id="presets"></ul>' +
   '</div>';
document.body.appendChild(div);

I ran a jsperf.com test, and first example is much slower, so why use it? Are there any other aspects I am missing?

lejahmie
  • 17,938
  • 16
  • 54
  • 77

3 Answers3

3

There is no real difference. Maybe the person writing that code didn't know you could split strings over multiple lines if you used the + operator?

They're equally good, that is to say, equally bad.


innerHTML is bad because it's hard to develop interactive applications. It's hard to modify (parts of) the HTML once you've outputted it. You'll need to insert ids everywhere, one for each element you want to reference later on. And if you're doing loops or generating very dynamic data you'll need some clever way to generate ids. If you want to add events innerHTML isn't going to help you. It's a real nightmare.

Wouldn't it be so much easier if you just had all the references to the elements? You could make a DSL that allows you to add events inline. Get references as you go. Use (variable-)scoping to deal with nested structures. etc.

Some examples of DFN libraries:

(Google for "DSL HTML generator" and you'll find more)


Related: (and a funny read) http://blog.korynunn.com/javascript/the-dom-isnt-slow-you-are/

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • Equally bad? Do you have a better suggestion on how to do it? – lejahmie Sep 11 '13 at 13:56
  • 1
    Don't use `innerHTML`. For smaller projects, and things like jQuery I can understand the temptation. I'll agree that the DOM API is clunky at best. A good solution for this is to use a specialized DFN language (DocumentFragmentNotation). – Halcyon Sep 11 '13 at 13:59
  • Now you really have my interest. :-) Why is `innerHTML` bad? And do you have any links to read up more about DFN? – lejahmie Sep 11 '13 at 14:02
  • @jamietelin Adding html as a string with innerHTML can cause unexpected errors if misspeling/errors will be in them – Sergey Kochetov Sep 11 '13 at 14:04
  • @SergeyKochetov Typos might happen anyway you do it. But putting a big chunk of HTML in the DOM with `innerHTML` must always be faster to insert and easier to read than creating each element and appending them? – lejahmie Sep 11 '13 at 14:07
  • 1
    Misspellings aside, `innerHTML` is not flexible enough. It doesn't allow you to (easily) build dynamic applications. I updated my answer. – Halcyon Sep 11 '13 at 14:13
3

That is entirely depends on the use-case.

Array will be useful if part of the array value used in some other places also,

In the below example(modified example of yours) I used both concat & array. I think this will clarify you :)

var div = document.createElement('div');
var div2 = document.createElement('div2');
var arrayData = [
       '<div id="view">' +
         '<button class="cancel">cancel</button>' +
         '<ul id="presets"></ul>'+
       '</div>',

       '<div id="view2">' +
         '<button class="submit">submit</button>' +
         '<ul id="presets"></ul>'+
       '</div>'
     ];

div.innerHTML = arrayData.join('');
// Only 1st index of arrayData string is needed here.
div2.innerHTML = arrayData[1];

document.body.appendChild(div);
document.body.appendChild(div2);
Arunprasad Rajkumar
  • 1,374
  • 1
  • 15
  • 31
2

Answer could be found here Old browsers (IE7-) worked faster with join rather than concatenation

Community
  • 1
  • 1
Sergey Kochetov
  • 390
  • 1
  • 7