2

What is the most recommended/efficient way to insert a node in the middle of a tree.

How to transpose this

<svg id="root" ... >
  <g id="child1">...</g>
  <text id="child2">...</text>
  <rect id="child3">...</rect>
  ...
</svg>

to this

<svg id="root" ... >
  <g id="parent">
    <g id="child1">...</g>
    <text id="child2">...</text>
    <rect id="child3">...</rect>
    ...
  </g>
</svg>

@jsFiddle

I have tried

var $parent = $("g").attr("id","parent");
var $root = $("#root");
$root.contents().each(function(){
   $child=$(this);
   $child.remove();
   $parent.append($child);
});
$root.append($parent);

I have also tried using the moveTo method in this answer

(function($){
    $.fn.moveTo = function(selector){
        return this.each(function(){
            var cl = $(this).clone();
            $(cl).appendTo(selector);
            $(this).remove();
        });
    };
})(jQuery);

$root.contents().each(function() {
    $(this).moveTo($parent);
});

All of these methods work in simple scenarios but when the tree is really massive, the browser simply hangs, is there a more efficient way to perform this?
I am looking for a jQuery or pure javascript solution.

Community
  • 1
  • 1
Jugal Thakkar
  • 13,432
  • 4
  • 61
  • 79

2 Answers2

4

I'd suggest:

$('#root > div').wrapAll('<div id="parent" />');

JS Fiddle demo.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Thanks for the quick answer, I wasn't aware about the wrapAll() method. It does the job of manipulating the DOM very effeciently, but the new element that I am wrapping around is a `g` element and the graphics doesn't show up after the manipulation [http://jsfiddle.net/jugal/mxc2x/2/]. If I manually (using firebug) edit the html to wrap the children of `svg` element around a `g` element everything works, i would assume the same should happen when done through javascript? The `g` shows up correctly inside the `svg` with all children moved but appears greyed out (like hidden elements) in firebug – Jugal Thakkar Sep 22 '12 at 20:21
  • Silly me, `$("#parent").show();` did the trick, but any idea why does it come up as hidden initially? – Jugal Thakkar Sep 22 '12 at 20:48
  • I honestly don't know; but mainly because I didn't want to wade through your demo. Um, sorry...I know, that sounds terrible... =( – David Thomas Sep 22 '12 at 20:50
  • 1
    No problem, I can understand :) Anyway it wasn't a part of the OP, may be I have a new question in hand ;) – Jugal Thakkar Sep 22 '12 at 20:55
0

This will make only one addition to the DOM, so this will be fast :

$('#root').html('<div id=parent>'+$('#root').html()+'</div>');
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    You forgot parens after `$('#root').html` and this would most likely destroy any listeners and data bound to those elements. – Fabrício Matté Sep 22 '12 at 19:55
  • Thanks for the quick response, I have also added a jsFiddle example, its an svg element that I am trying to manipulate. Let me try your suggestion till you have a look at the fiddle – Jugal Thakkar Sep 22 '12 at 19:56