我试图克隆一个节点,该节点是另一个节点的子节点,但是js不允许我为HTMLCollection / NodeList数据类型建立索引。每当我尝试索引该数据类型时,它总是导致未定义的值。即使按照Most efficient way to convert an HTMLCollection to an Array将该数据类型转换为数组,我仍然无法索引该数组。
var viewports = document.getElementsByClassName('imageViewerViewport');
console.log(viewports[0].childNodes) // In the console shows the children I expect to see
console.log(viewports[0].childNodes.item(0)) // Nothing shows up - undefined
console.log(viewports[0].childNodes.item(1)) // Nothing shows up - undefined
console.log(viewports[0].children.item(0)) // Nothing shows up - undefined
console.log(viewports[0].children.item(1)) // Nothing shows up - undefined
console.log(viewports[0].childNodes[0]) // Nothing shows up - undefined
console.log(viewports[0].childNodes[1]) // Nothing shows up - undefined
console.log(viewports[0].children[0]) // Nothing shows up - undefined
console.log(viewports[0].children[1]) // Nothing shows up - undefined
console.log("Here")
var second_canvas = viewports[0].children.item(1).cloneNode(true); // Error that is detailed below
viewports[1].appendChild(second_canvas);
克隆节点会产生错误:Cannot read property 'cloneNode' of undefined
。
答案 0 :(得分:0)
所以答案是并非所有childNodes
都是有效的Node
这是详细版本,我们在其中记录以显示无效节点。
const cloneThings = () => {
document.querySelectorAll('.cloneMyChildren').forEach(parentNode => {
console.log(parentNode.classList.length);
parentNode.childNodes.forEach(child => {
console.log(child.outerHTML); // This is here to show, the child nodes are NOT all HTMLElements.
if(child.outHTML) {
const childClone = child.cloneNode(true);
childClone.classList.add('clone');
document.body.appendChild(childClone);
}
});
});
};
document.addEventListener('click', ({ target }) => {
if(target.matches('button')) {
cloneThings();
}
});
.cloneMe {
border: 1px solid red;
}
.clone {
border: 1px solid blue;
}
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<button>Clone Stuff</button>
这是一个更简洁的版本。
const cloneThings = () => {
Array.from(document.querySelectorAll('.cloneMyChildren'))
.flatMap(p => Array.from(p.childNodes).filter(c => c.outerHTML !== undefined))
.forEach(n => {
const childClone = n.cloneNode(true);
childClone.classList.add('clone');
document.body.appendChild(childClone);
});
};
document.addEventListener('click', ({ target }) => {
if(target.matches('button')) {
cloneThings();
}
});
.cloneMe {
border: 1px solid red;
}
.clone {
border: 1px solid blue;
}
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<div class="cloneMyChildren">
<span class="cloneMe">Clone Me</span>
<span class="cloneMe">Clone Me</span>
</div>
<button>Clone Stuff</button>