我正在尝试克隆一个节点,该节点是另一个节点的子节点,但是js不允许我索引HTMLCollection/NodeList数据类型。每当我尝试索引该数据类型时,它总是会导致未定义的值。即使我按照将 HTMLCollection 转换为数组的最有效方法将该数据类型转换为数组,我仍然无法为数组编制索引。
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
。
所以答案是并非所有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>