Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

retain reference to appended node javascript

No libraries please. Beyond my control.

I'm appending a document fragment to the dom. THIS ALL WORKS. No problemo.

How do I retain/retrieve the node list after the fragment is appended? Relevant code:

var frag = document.createDocumentFragment();
//add some content to the fragment
element.appendChild(frag);

Again, this works! I do NOT need a troubleshoot on how to add things to the dom!

If I set var e = element.appendChild(frag);, everything gets appended normally, but e = an empty document fragment.

I'm looking for some smooth magic voodoo here. Don't send me looping over the entire dom. The content could be anything, one or many nodes with or without children. If there's some trick with querySelectorAll or something that would be acceptable.

Thanks!

EDIT Upon further poking, it appears that e above is in fact a returned reference to the frag var, that is empty after appending it to the dom. It's much like the elements were neatly slid off of the fragment into the dom, and the fragment just lays around empty.

like image 683
Randy Hall Avatar asked Nov 09 '12 20:11

Randy Hall


4 Answers

It's exactly what you've described; when the elements are appended to an element, they're removed from the fragment to prevent memory leaks from lingering references.

One way to get those child nodes is to make a shallow copy of the fragment's childNodes before doing appendChild():

// make shallow copy, use Array.prototype to get .slice() goodness
var children = [].slice.call(frag.childNodes, 0);

element.appendChild(frag);

return children;
like image 71
Ja͢ck Avatar answered Nov 08 '22 10:11

Ja͢ck


If you're looking just after appending it, the lastChild is the way to go. Use it like this:

var e = element.lastChild;

More info in SitePoint

like image 29
Serabe Avatar answered Nov 08 '22 10:11

Serabe


From doc of DocumentFragment:

Various other methods can take a document fragment as an argument (e.g., any Node interface methods such as appendChild and insertBefore), in which case the children of the fragment are appended or inserted, not the fragment itself.

So appendChild method return the documentFragment but it's empty because its child nodes are inserted in your element object and (from appendChild doc):

[...] a node can't be in two points of the document simultaneously. So if the node already has a parent, it is first removed, then appended at the new position.

Now... You can store in a cache array your children and after return it (or see Jack solution :-))

like image 2
Luca Rainone Avatar answered Nov 08 '22 10:11

Luca Rainone


Like Jack's solution, but if you are using esnext you could use Array.from as

const children = Array.from(frag.children);

element.appendChild(frag);

return children;
like image 2
Gabe M Avatar answered Nov 08 '22 11:11

Gabe M