4

Suppose I have a partial dom tree with a parent node and a set of children.

How can I interject a DIV between them?

I am starting with

parent --+--> child[0]
         |--> child[1]
         |--> child[2]

..and I want to end with

parent ---> newdiv ---+--> child[0]
                      |--> child[1]
                      |--> child[2]

How can I do this?

I need the converse of replaceChild() . Is there something like replaceParent() ?

I suppose I could clone all the child nodes, and then insert them as children in the new node. but... does that retain all the element ids?


EDIT - I didn't tag this with jQuery, or any framework, but maybe I should have been explicit about it. This is not a jQuery question. I want to do this in javascript + DHTML. No extra or outside framework.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • I think cloning all the child nodes will be your best bet... looking at the jQuery source for `wrapAll` (which I think does pretty much what you're looking for), that appears to be what is done (although I haven't analysed it thoroughly): http://james.padolsey.com/jquery/#v=1.6.2&fn=jQuery.fn.wrapAll If you can use jQuery, I'd suggest that! – James Allardice Oct 08 '11 at 22:26
  • 1
    Correct, `wrapAll()` does the trick: http://jsfiddle.net/2U7rm/1/ – Tomasz Nurkiewicz Oct 08 '11 at 22:29

3 Answers3

5

You can just move elements around by appending them to a new parent. In plain javascript:

var newDiv = document.createElement("div");

while(parent.hasChildNodes())
    newDiv.appendChild(parent.firstChild);

parent.appendChild(newDiv);

From the documentation of W3C about appendChild:

Adds the node newChild to the end of the list of children of this node. If the newChild is already in the tree, it is first removed.

Elian Ebbing
  • 18,779
  • 5
  • 48
  • 56
  • just to clarify - appending an element to a new parent, removes it's relationship with the existing parent. is that right? – Cheeso Oct 09 '11 at 03:47
  • @Cheeso - Yes, see the notes on https://developer.mozilla.org/En/DOM/Node.appendChild. It works this way in every browser. – Elian Ebbing Oct 09 '11 at 16:26
0

As an alternative to using .firstChild, one can also use .firstElementChild. The property .firstChild can return textNodes that just contains the formatting text from the HTML; i.e., the first child might just be a textNode with a nodeValue = \n .

Consider the following snippet if you want to only move children elements, not textNodes:

    const newDiv = document.createElement("div");

    // Insert a new div in between a parent and its children
    while (parent.childElementCount > 0) {
        newDiv.appendChild(parentDiv.firstElementChild);
    }
    parentDiv.appendChild(newDiv)

See this for details on how an HTML file's whitespace can remain part of an active DOM.

Josh Desmond
  • 640
  • 2
  • 10
  • 19
0
$('.child').wrapAll('<div class="newdiv"></div>');

More info: http://api.jquery.com/wrapAll/

Ahmet Recep Navruz
  • 713
  • 11
  • 14