为什么 Insert before first child 不起作用

Why Insert before first child not working

如果元素有 children 插入一个新的 div "i-new-element"。 parent2 和 parent3 得到一个新的 div.

child3-parent3 有 children 但没有得到新的巨人。为什么?

我怎样才能让拥有 children 的 children 获得新的 div?

它应该看起来像:

<div id="child3-parent3">
  <div id="i-new-element"></div>
  <div id="child3"></div>
  <div id="child4"></div>
</div>

var container = document.getElementById("container").querySelectorAll("#container > *");

container.forEach(function(div) {
  {
    if (div.hasChildNodes()) {
      let parentElement = div;
      let theFirstChild = parentElement.firstChild;
      let newElement = document.createElement("div")
      newElement.id = "i-new-eleemnt"
      parentElement.insertBefore(newElement, theFirstChild)
    }
  }
});
<div id="container">
  <div id="parent1"></div>
  <div id="parent2">
    <div id="child1"></div>
    <div id="child2"></div>
    <div id="child3-parent3">
      <div id="child3"></div>
      <div id="child4"></div>
    </div>
  </div>
  <div id="parent3">
    <div id="child5"></div>
    <div id="child6"></div>
  </div>
</div>

正在使用

var container = document.getElementById("container");
var elements = container.querySelectorAll(":scope *");

而不是

var container = document.getElementById("container").querySelectorAll("#container > *");

应该可以解决您的问题。

var container = document.getElementById("container");
   var elements = container.querySelectorAll(":scope *");

elements.forEach(function(div){
  {
    if (div.hasChildNodes()) {
      let parentElement = div;
      let theFirstChild = parentElement.firstChild;
      let newElement = document.createElement("div")
      newElement.id = "i-new-eleemnt"
      parentElement.insertBefore(newElement, theFirstChild)
    }
  }
});
<div id="container">
  <div id="parent1"></div>
  <div id="parent2">
    <div id="child1"></div>
    <div id="child2"></div>
    <div id="child3-parent3">
      <div id="child3"></div>
      <div id="child4"></div>
    </div>
  </div>
  <div id="parent3">
    <div id="child5"></div>
    <div id="child6"></div>
  </div>
</div>


编辑:关于:scope CSS伪class的更多信息可以在here and here.[=16中找到=]

我认为您的问题如下,即使您的示例中没有很好地描述它 HTML:

<div id="parent1"></div> 每个实例实际上不是一个空节点,而是包含一些文本,即 <div id="parent1">some text here</div>.

信不信由你,但是node.hasChildNodes()会将任何文本算作子节点(文本节点,nodeType = 3),所以它总是return true是任何文本存在。

为避免这种情况,您可以先过滤文本节点或使用此解决方法:

替换此行:

if (div.hasChildNodes()) {

那一行:

if (div.children.length) {

children 属性 不计算文本节点。

我相信这就是您要做的全部。

var container = document.querySelectorAll("#container > *");

container.forEach(function(div) {
  {
    if (div.children.length) {
      let parentElement = div;
      let theFirstChild = parentElement.children[0];
      let newElement = document.createElement("div")
      newElement.id = "i-new-eleemnt";
      newElement.innerHTML = 'i-new-eleemnt'
      parentElement.insertBefore(newElement, theFirstChild);
    }
  }
});
<div id="container">
  <div id="parent1">parent1</div>
  <div id="parent2">parent2
    <div id="child1">child1</div>
    <div id="child2">child2</div>
    <div id="child3-parent3">child3-parent3
      <div id="child3">child3</div>
      <div id="child4">child4</div>
    </div>
  </div>
  <div id="parent3">parent3
    <div id="child5">child5</div>
    <div id="child6">child6</div>
  </div>
</div>