childNode意外行为

时间:2018-07-13 07:59:40

标签: javascript html dom simple-html-dom

场景

我想获取div的所有子节点并更改其颜色。 代码:

function myFunction() {
  var divv = document.getElementById("divv");
  var myCollection = divv.childNodes;
  var len = myCollection.length;
  var i;
  for (i = 0; i < len; i++) {
    myCollection[i].style.color = "red";
  }
}
<div id="divv">

  <h2>JavaScript HTML DOM</h2>

  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>

  <button onclick="myFunction()">Try it</button>
</div>

错误: 这是行不通的。在我的收藏夹中似乎我拥有所有节点。 h2 p文字按钮。我只参加了p h2和buton。

编辑 说明 注意:元素内部的空格被视为文本,而文本被视为节点。注释也被视为节点。

因此,我们需要检查节点是否为元素节点,或使用querySelectorAll。 下面的答案示例。感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

文本节点没有style属性。如果要使用childNodes,请首先检查nodeType是否为1(一个Element节点):

function myFunction() {
  var divv = document.getElementById("divv");
  var myCollection = divv.childNodes;
  var len = myCollection.length;
  var i;
  for (i = 0; i < len; i++) {
    if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
  }
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>

但是我更喜欢在这里使用querySelectorAllforEach

function myFunction() {
  document.querySelectorAll('#divv > *')
    .forEach(child => child.style.color = "red");
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>

(或者,您可以将#divv的{​​{1}}设置为红色)

答案 1 :(得分:3)

您可以使用children属性来访问给定节点的子代:

  

ParentNode属性children是一个只读属性,它返回一个实时HTMLCollection,其中包含被调用的节点的所有子元素。

     

-MDN web docs

function myFunction() {
  var divv = document.getElementById("divv");
  var myCollection = divv.children;
  var len = myCollection.length;
  var i;
  for (i = 0; i < len; i++) {
    myCollection[i].style.color = "red";
  }
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>


使用ES6的另一种方法是将子节点散布到一个数组中,并使用.forEach遍历它们:

const myFunction = () => {
  
  [...document.querySelector('#divv').children].forEach(child => {
  
    child.style.color = 'red';
  
  });
  
}
<div id="divv">
  <div class="child">
    I am a child
  </div>
  <div>
    <div class="grandchild">
      I am a grand child
    </div>
  </div>
  
  <button onclick="myFunction()">Try it</button>
</div>

或者,您可以直接使用.forEach类中的NodeList,但是前一种方法为您提供了更多使用Array方法的自由度,例如.reduce.map,等等...

const myFunction = () => {
  
  document.querySelectorAll('#divv > *').forEach(child => {
  
    child.style.color = 'red';
  
  });
  
}
<div id="divv">
  <div class="child">
    I am a child
  </div>
  <div>
    <div class="grandchild">
      I am a grand child
    </div>
  </div>
  
  <button onclick="myFunction()">Try it</button>
</div>