Frage

I've discovered a behavior with cloneNode(true) that was unexpected, and thought I'd document it for two reason. #1 - get corroboration from others that what I think I see is true. #2 - Give others that run into this issue a heads up as I found no reference to this issue on this site.

// var's not shown.
danglingNode = document.getElementById('Master').cloneNode(true);
// Modify all id names to make them unique.
allElements = danglingNode.getElementsByTagName('id');
for (i = 0; i < allElements.length; ++i) {
   ...
}

The allElements.length returns 0, even though I know there are numerous elements that do contain an id tag name.

For testing, I changed 'id' to 'input' and the length is now accurate, meaning that the tree structure is there, but that it is inaccessible via 'id'. I wrote a DOM walker function and sure enough, the tree is there and loaded with id tag names. The conclusion I draw is that the duplicate id names resulting from the clone are making retrieval via id impossible. The Mozilla developer site warns that cloning will result in duplicate id's and suggests modifying those duplicates to again achieve uniqueness, but does not offer a way to accomplish it. I thought a simple loop would suffice, but that's apparently not true.

I tried creating a fragment ( document.createDocumentFragment() ) and appending the danglingNode below it to see if that would provide access via 'id', but no such luck.

Eventually I decided to use the DOM walker previously mentioned to not only walk the tree, but fix it along the way with new id names. That function is below:

function fixIds(element, prefix) {
   "use strict";
   // This is a recursive function, designed to walk the tree below "element"
   // and modify all id values by prefixing the existing id with a fixed "prefix".
   do {
      // console.log('typeof = ' + typeof element.id)
      if (typeof element.id === 'string' && element.id !== '') {
      if (debug) {console.log(element.id + ' -> ' + prefix + element.id);}
         element.id = prefix + element.id;
      }
      if (element.hasChildNodes()) {
            fixIds(element.firstChild, prefix);
      }
   } while (element = element.nextSibling);
}

Does anyone have another way of handling a cloned structure to modify the duplicate id's?

Can anyone see anything wrong with what I've done?

Have I missed something obvious?

War es hilfreich?

Lösung

id is an attribute, not a tag, so getElementsByTagName('id') will not work.

You could loop through the danglingNode elements checking their id each time.

for (i = 0; i < danglingNode.length; ++i) {
    if (!danglingNode[i].id) {
        // no id, do something
    }
}

If the nodes are nested then you'll need to use a recursive (DOM walking) process instead.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top