0
function fooBar() {
  var creation = document.createElement('div');
  creation.appendChild(document.createElement('div'));
}

So up there is a pretty ugly scenario. I often encounter moments where I just want to reuse one of these by cloning or whatever. Im not sure if im overthinking this but something just doesnt seem right. Is it possible to optimize this code?

Asperger
  • 3,064
  • 8
  • 52
  • 100
  • 1
    if you want cloning, then just use it, there is a [`node.cloneNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) method. – Kaiido Dec 26 '15 at 13:16
  • @Kaiido below the user used innerHTML but shouldnt innerHTML be avoided? – Asperger Dec 26 '15 at 13:17
  • 2
    You talk about security reasons, but the only concerns would come if you do append some user's input or from untrusted sources. What is IMO bad in this habit of using innerHTML is that you are asking the browser to re-parse the string, which is, if I do remember correctly, slower than using the DOM for creating nodes. Also, if you do need to get the created node, you'll make an other call to a DOM method (such as `querySelector`) which would be avoided with well written node creation. – Kaiido Dec 26 '15 at 13:21
  • @Kaiido great info and upvoted. – Asperger Dec 26 '15 at 13:22
  • @Kaiido http://stackoverflow.com/questions/2946656/advantages-of-createelement-over-innerhtml – Asperger Dec 26 '15 at 13:25
  • accepted answer is great, but you're in none of its cases. However the question is quite old and I'm not sure e.g Pekka's answer is still right about the speed : https://jsperf.com/clonenode-vs-createelement-performance/32 On my machine, cloneNode is way faster than any other method, and also, in my codes, I think it's clearer. – Kaiido Dec 26 '15 at 13:36
  • @Kaiido I actually chose cloneNode as the solution due to that reason. I really think it is elegant – Asperger Dec 26 '15 at 13:38
  • @Kaiido you should post this as an answer. You got some really high quality content there. I think it deserves to be the accepted answer. – Asperger Dec 26 '15 at 13:42

2 Answers2

0

how about this one

var creation = document.createElement('div');
creation.innerHTML = "<div></div>";

to get the element

el = creation.querySelector("div");
user3896501
  • 2,987
  • 1
  • 22
  • 25
  • It uses innerHTML. I prefer to avoid it. Unless im missing out some information. – Asperger Dec 26 '15 at 13:15
  • As far as im aware innerHTML should be avoided due to security concerns. – Asperger Dec 26 '15 at 13:16
  • I think the appendChild can't be further optimized, how about use jQuery for better syntax looks? – user3896501 Dec 26 '15 at 13:18
  • Ya jquery could do the job but then I have 1000000 lines of extra code just for this one feature hehe. I prefer vanilla js because that : ) – Asperger Dec 26 '15 at 13:19
  • 1
    @Asperger `innerHTML` is fine. How could it possibly be a security concern if you are supplying the content yourself? – Jared Smith Dec 26 '15 at 13:20
  • 2
    @Asperger You can use `innerHTML` with trusted strings, avoid it with user generated strings – jbmartinez Dec 26 '15 at 13:20
  • I remember there were a few that told me to avoid it at all cost which is why I have been kind of of reluctant – Asperger Dec 26 '15 at 13:23
  • http://stackoverflow.com/questions/2946656/advantages-of-createelement-over-innerhtml – Asperger Dec 26 '15 at 13:25
  • @Asperger if all HTML inside the string which proposed to being innerHTMLed is not entered by user, then innerHTML is safe – user3896501 Dec 26 '15 at 13:26
  • 1
    @Asperger that question and its answers are ***5 years old***. In any form of software development but *especially* web dev where everything changes much faster take anything that old with a *very* large grain of salt. Even if the technology doesn't change, best practices do. – Jared Smith Dec 26 '15 at 13:31
  • @JaredSmith Oh I see. I didnt know that. So dont the points apply anymore? – Asperger Dec 26 '15 at 13:37
  • @JaredSmith you're so right about the question's age, but it actually seem to have gone against innerHTML lately https://jsperf.com/clonenode-vs-createelement-performance/32 – Kaiido Dec 26 '15 at 13:37
  • @Asperger, no the points made in the accepted answer are still correct and should still be thought of when we do **modify** the innerHTML of an element – Kaiido Dec 26 '15 at 13:39
  • @Kaiido which we dont. We just add new elements. Which doesnt make it the perfect solution for the job? Looking at the test within the link you supplied it seems pretty obvious that cloneNode is the candidate – Asperger Dec 26 '15 at 13:39
  • @Asperger both `createElement` and `cloneNode` needs lots of lines to instantiate the elements, also `cloneNode` requires `createElement` as well before cloning, in the benchmark the div already created before benchmark starts, so `cloneNode` faster than `createElement`. If you wants performance you might go for `createElement`, but if you don't want too much `createElement` in your code, `innerHTML` is your choice – user3896501 Dec 26 '15 at 13:46
0

Rather than continuing conversation in comments, I will simply post an answer.

Short Answer:

It doesn't matter in the slightest.

Longer Answer:

If by optimization you mean execution time, the difference is irrelevant unless you are creating 1000's of elements. If by optimization you mean good DRY code, then I would say your entire approach is incorrect: use templating instead.

The number of possible methods of templating make enumerating them beyond the scope of this answer, but anything from PHP (if that's how you roll) to Handlebars to custom regex replacements will get the job done. But about the only time I call document.createElement is for concurrent script bootstrapping that maintains execution order: see this for more details.

So to summarize, use re-usable templates. If the items need to be created dynamically then use client-side rendering. For everything else, use server-side rendering. Avoid manually creating elements as that's pretty low-level, prefer more abstract solutions like the one I suggested.

Community
  • 1
  • 1
Jared Smith
  • 19,721
  • 5
  • 45
  • 83