cloneNode() and removeChild() are broken

by @jehiah on 2006-08-25 18:17UTC
Filed under: All , HTML , Articles , Javascript , IE , Firefox , Web

If you use cloneNode() or removeChild() when writing javascript, be aware that they are both broken. very broken

From the W3C DOM Level 2 specification of cloneNode() (emphasis mine)

cloneNode() Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes. […] Cloning an Element copies all attributes and their values, those generated by the XML processor to represent defaulted attributes …

If only it were so. Problem is that when you clone a node from the DOM tree in Internet Explorer any changes to that node after page load are not cloned. This is true even when you do a deep-copy clone.

I’ve created an example page that shows that even a simple action like checking a checkbox will not be reflected on a cloned copy.

That hurts. Now as javascript developers we have to implement our own cloneNode methods to do what Internet Explorer should have been doing all along.

But it gets worse, not only does cloneNode suffer from amnesia, the same problems happen when you even remove a node from the DOM tree and immediately add it back in. It looses attributes. Thats bad. real bad.

Again quoting the W3C DOM Level 2 specification on removeChild()

removeChild(oldChild) Removes the child node indicated by oldChild from the list of children, and returns it.

Say you want to move an element from one section of the page to another

[js]
elementToMove = document.getElementById("targetElement");
elementToMove.parentNode.removeChild(elementToMove);
document.getElementById("targetArea").appendChild(elementToMove);
[/js]

That all looks straight forward enough.. right? Problem is that as soon as you call removeChild it looses attributes. If it’s a check box that was checked before, now it’s just a checkbox. Thats bad as well. real bad

The DOM specification above certainly didn’t say anything about changing attributes when you use it. It said it would return the node, not something similar to the node.

No problem the removeChild part is actually optional in this usage, that happens automatically when you appendChild right? not to be fooled, the same problem persists if you just use appendChild() to insert it in the same place without removing it first. attributes are lost.

Here is an example page showing this problem as well

what to do?

I wish I knew. If you have thoughts about this please leave them below

Subscribe via RSS ı Email
Jehiah Czebotar