2

Is it possible to add something with innerHTML before/after the nth child of <body>?

e.g.:

<html>
<head></head>
<body>
<div id="first">First</div>
<div id="second">Second<div id="second_sub"></div></div>
<div id="third">Third</div>
</body>
</html>

I can add at the beginning with body.innerHTML = html + body.innerHTML and at the end with body.innerHTML += html but how to add, for example, before the second <div>?

I don't want to use replace on <div id="second"> as the source changes and the insert should be done at random. Is there a solution with innerHTML or do I need to switch to Dom Nodes? Would be slow in old browsers :(

Borodin
  • 126,100
  • 9
  • 70
  • 144
mgutt
  • 5,867
  • 2
  • 50
  • 77
  • 1
    I would have an empty div and then put the stuff inside, but I once heard that having empty tags is a bad CEO practice – ajax333221 Feb 26 '12 at 19:12
  • Look at: http://msdn.microsoft.com/en-us/library/ms536452%28v=vs.85%29.aspx. I'm not sure if this can be used in other browsers. – Teemu Feb 26 '12 at 19:18
  • @ajax333221 You mean like that: http://stackoverflow.com/a/814649/318765 ? Looks like a good option for me. Other ideas? – mgutt Feb 26 '12 at 19:49
  • 1
    "Would be slow in old browsers"?! Dom functions is faster for such operations, than innerHTML even in IE6. Even if insertion of first node is slower 2-5 times, DOM insertion work with the same speed, whilst working with html string will force browser to parse and re-create all child DOM nodes each time. – kirilloid Feb 26 '12 at 19:59
  • 1
    @ kirilloid You are wrong: http://www.quirksmode.org/dom/innerhtml.html – mgutt Mar 01 '12 at 13:13

2 Answers2

2

You are probably looking for the insertBefore method. It will insert a child before the given element. Alternatively there's the appendChild method which will always push elements on the beginning of the given element. Examples:

<body>
    <span id="elem1">Hello</span>
    <span id="elem2">World</span>
</body>

Let's assume we're inserting a new element stored in the var newElem: document.insertBefore(newElem, document.getElementById("elem2")) will give:

<body>
    <span id="elem1">Hello</span>
    <!-- New element here! -->
    <span id="elem2">World</span>
</body>

document.appendChild(newElem) will give:

<body>
    <!-- New element here! -->
    <span id="elem1">Hello</span>
    <span id="elem2">World</span>
</body>
Jens Egholm
  • 2,730
  • 3
  • 22
  • 35
  • 1
    Generally, MDN is a [better](http://w3fools.com) resource than w3shools: [`insertBefore`](https://developer.mozilla.org/en/DOM/Node.insertBefore) and [`appendChild`](https://developer.mozilla.org/en/DOM/element.appendChild). – Rob W Feb 26 '12 at 21:20
  • As I said: I don't want to use DOM nodes as this could extremly blow up the code. But a solution would be the combination of both. I will post an answer. – mgutt Feb 27 '12 at 20:14
2

I'm using this by now (Thanks to ajax333221):

e = document.createElement('div');
e.innerHTML = '<div>... huge content with several sub elements ...</div>';
document.body.insertBefore(e, document.body.childNodes[2]);

This is a combination of both techniques. With this I'm able to use the fast .innerHTML without extremely blowing up the code with createElement(), setAttribute(), etc.

Other solutions are welcome.

mgutt
  • 5,867
  • 2
  • 50
  • 77