所以我们都知道document.getElementsByClassName
和document.getElementsByTagName
是实时的HTMLCollections。
我用谷歌搜索,似乎找不到答案,也许我只是不明白,谁能向我解释?
所以我做了两个例子,一个是添加类属性,另一个是 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"类替换为"green"
如果您添加一个类而不是使用ele.classList.add(class)
替换当前类,这将起作用
https://jsfiddle.net/84ryjp7s/3/
好吧,为可能有相同问题的人总结一下。
因此,如果您获得带有 ClassName 的集合,则意味着在您删除用于收集集合的当前类之前,一切都将正常运行。
如果是class="a b",你可以添加任何类,但如果你删除/更改其中一个,它会破坏HTML集合
与任何其他 HTML 节点列表/实时节点列表相同
如果你使用 getElementsByTagName 聚集,你可以改变类,但你不能改变 td,如果你试图删除div,你就毁了集合
https://jsfiddle.net/adkuca/c00fqmts/
因为它计算你正在删除TD,因此追逐HTML集合,将其缩小1,因此将ran.length缩小1,因此你得到一半的迭代,你添加新的TD少一半。
检查此内容:https://jsfiddle.net/adkuca/c7jb0es8/
但是如果你真的想用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>