childNode 意外行为
childNode unexpected behaviour
场景
我想获取 div 的所有 child 节点并更改其颜色。
代码:
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>
错误:
这是行不通的。似乎在我的 collection 中我拥有所有节点。 h2 p 文本按钮。我只期望 p h2 和按钮。
编辑
说明
注意:元素内部的空白被认为是文本,文本被认为是节点。评论也被视为节点。
所以我们需要检查节点是否为元素节点,或者使用querySelectorAll。
以下答案中的示例。感谢您的帮助。
您可以使用 children
属性 访问给定节点的子节点:
The ParentNode
property children
is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
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
from the NodeList
class,但之前的方法让您可以更自由地使用 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>
文本节点没有 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>
但我更喜欢在这里使用 querySelectorAll
和 forEach
:
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
的 style.color
设置为红色)
场景
我想获取 div 的所有 child 节点并更改其颜色。 代码:
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>
错误: 这是行不通的。似乎在我的 collection 中我拥有所有节点。 h2 p 文本按钮。我只期望 p h2 和按钮。
编辑 说明 注意:元素内部的空白被认为是文本,文本被认为是节点。评论也被视为节点。
所以我们需要检查节点是否为元素节点,或者使用querySelectorAll。 以下答案中的示例。感谢您的帮助。
您可以使用 children
属性 访问给定节点的子节点:
The
ParentNode
propertychildren
is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
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
from the NodeList
class,但之前的方法让您可以更自由地使用 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>
文本节点没有 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>
但我更喜欢在这里使用 querySelectorAll
和 forEach
:
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
的 style.color
设置为红色)