HTMLCollection 添加不同的属性对实时集合的影响不同,需要解释
HTMLCollection adding different attributes affects the live collection differently, need explanation
所以我们都知道 document.getElementsByClassName
和 document.getElementsByTagName
是实时 HTML 集合。
我用谷歌搜索,似乎找不到这个问题的答案,也许我只是不明白,谁能给我解释一下?
所以我做了 2 个示例,一个添加了 class 属性,另一个添加了 bgcolor。为什么第一个按预期行事,而另一个却完成了工作...
为什么 TagName 的工作方式不同,即使它是第一个示例中的 HTMLCollection?
我怎么知道哪个可以正常工作,哪个不能正常工作?
https://jsfiddle.net/adkuca/84ryjp7s/2/
https://jsfiddle.net/adkuca/f1o9h7be/
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
ran[i].setAttribute("class", "green");
}
console.log(ran); //HTMLCollection, all 6 with TagName, every 2nd with ClassName
console.log(ran.length); //6 with TagName, 3 with ClassName
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
.green {
background-color: green;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
ran[i].setAttribute("bgcolor", "green");
}
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>
它们都以相同的方式正常工作。 className 的工作方式似乎有所不同,因为您在处理它时有效地从正在使用的列表中删除了元素。
当您使用 setAttribute("class", "green");
时,您将 "wasd" class 替换为 "green"
如果您添加 class 而不是使用 ele.classList.add(class)
替换当前的,这将起作用
好吧,给可能有同样问题的人总结一下。
所以如果你得到一个带有 ClassName 的集合,意味着一切都会正常运行,直到你删除当前的 class 你用来收集集合。
如果它是 class="a b",您可以添加任何 class,但如果您 delete/change 其中 1 个它会破坏 HTML 集合
与任何其他相同HTML集合/实时节点列表
如果你用 getElementsByTagName 收集,你可以改变 class 但你不能改变 td,如果你试图删除 div,你毁了收集
https://jsfiddle.net/adkuca/c00fqmts/
因为它计算你正在删除 td,因此改变 HTML 集合,将其缩小 1,因此将 ran.length 缩小 1,所以你得到一半迭代,然后添加一个新的 td 少了一半。
检查这个:https://jsfiddle.net/adkuca/c7jb0es8/
但如果你真的想收集 classes 和 classname 然后更改它们,你可以将它们存储到一个数组中然后更改。
Array.from(document.getElementsByClassName('wasd')).forEach(function(itm){
itm.setAttribute('replaced-wasd');
});
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
console.log(ran.length);
ran[i].setAttribute("class", "green");
console.log(ran.length);
console.log("i = " + i);
console.log(ran);
}
console.log(ran); //HTMLCollection, all 6 with TagName, every 2nd with ClassName
console.log(ran.length); //6 with TagName, 3 with ClassName
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
.green {
background-color: green;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>
所以我们都知道 document.getElementsByClassName
和 document.getElementsByTagName
是实时 HTML 集合。
我用谷歌搜索,似乎找不到这个问题的答案,也许我只是不明白,谁能给我解释一下?
所以我做了 2 个示例,一个添加了 class 属性,另一个添加了 bgcolor。为什么第一个按预期行事,而另一个却完成了工作...
为什么 TagName 的工作方式不同,即使它是第一个示例中的 HTMLCollection?
我怎么知道哪个可以正常工作,哪个不能正常工作?
https://jsfiddle.net/adkuca/84ryjp7s/2/
https://jsfiddle.net/adkuca/f1o9h7be/
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
ran[i].setAttribute("class", "green");
}
console.log(ran); //HTMLCollection, all 6 with TagName, every 2nd with ClassName
console.log(ran.length); //6 with TagName, 3 with ClassName
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
.green {
background-color: green;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
ran[i].setAttribute("bgcolor", "green");
}
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>
它们都以相同的方式正常工作。 className 的工作方式似乎有所不同,因为您在处理它时有效地从正在使用的列表中删除了元素。
当您使用 setAttribute("class", "green");
时,您将 "wasd" class 替换为 "green"
如果您添加 class 而不是使用 ele.classList.add(class)
好吧,给可能有同样问题的人总结一下。
所以如果你得到一个带有 ClassName 的集合,意味着一切都会正常运行,直到你删除当前的 class 你用来收集集合。
如果它是 class="a b",您可以添加任何 class,但如果您 delete/change 其中 1 个它会破坏 HTML 集合
与任何其他相同HTML集合/实时节点列表
如果你用 getElementsByTagName 收集,你可以改变 class 但你不能改变 td,如果你试图删除 div,你毁了收集
https://jsfiddle.net/adkuca/c00fqmts/
因为它计算你正在删除 td,因此改变 HTML 集合,将其缩小 1,因此将 ran.length 缩小 1,所以你得到一半迭代,然后添加一个新的 td 少了一半。
检查这个:https://jsfiddle.net/adkuca/c7jb0es8/
但如果你真的想收集 classes 和 classname 然后更改它们,你可以将它们存储到一个数组中然后更改。
Array.from(document.getElementsByClassName('wasd')).forEach(function(itm){
itm.setAttribute('replaced-wasd');
});
var ran = document.getElementsByClassName('wasd');
/*var ran = document.getElementsByTagName('td');*/
document.getElementById('btn').addEventListener('click', func);
function func() {
console.log(ran); //HTMLCollection, all 6
console.log(ran.length); //6 with both
for (let i = 0; i < ran.length; i++) {
console.log(ran.length);
ran[i].setAttribute("class", "green");
console.log(ran.length);
console.log("i = " + i);
console.log(ran);
}
console.log(ran); //HTMLCollection, all 6 with TagName, every 2nd with ClassName
console.log(ran.length); //6 with TagName, 3 with ClassName
}
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
.green {
background-color: green;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id="btn">func</button>
<table>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
<tr>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
<td class="wasd"></td>
</tr>
</table>
</body>
</html>