所以我们都知道document.getElementsByClassName
和document.getElementsByTagName
是实时HTMLCollections。
我用谷歌搜索,似乎无法找到答案,也许我只是没有得到它,谁可以向我解释?
所以我做了两个例子,一个添加了一个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
}
&#13;
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
.green {
background-color: green;
}
&#13;
<!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>
&#13;
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
}
&#13;
tr, td {
border: 1px solid black;
height: 20px;
width: 20px;
}
&#13;
<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>
&#13;
答案 0 :(得分:0)
他们都以同样的方式正常工作。 className似乎工作方式不同,因为你正在有效地从你正在使用的列表中删除元素,而你正在经历它。
当您使用setAttribute("class", "green");
时,您将“wasd”类替换为“green”
如果您添加一个类而不是使用ele.classList.add(class)
答案 1 :(得分:0)
好的总结一下可能有同样问题的人。
所以如果你得到一个带有ClassName的集合,意味着一切都会正常运行,直到你删除你收集集合的当前类。
如果它是class =“a b”,你可以添加任何类,但是如果删除/更改其中的一个,它会破坏HTML集合
与任何其他HTMLCollection / live NodeList相同
如果你使用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>