为 HtmlCollection 或 NodeList 编制索引



我正在尝试克隆一个节点,该节点是另一个节点的子节点,但是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>

最新更新