添加不同属性的HTMLCollection会以不同方式影响实时收藏,需要解释

时间:2018-01-19 17:37:18

标签: javascript dom live

所以我们都知道document.getElementsByClassNamedocument.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;
&#13;
&#13;

&#13;
&#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;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

他们都以同样的方式正常工作。 className似乎工作方式不同,因为你正在有效地从你正在使用的列表中删除元素,而你正在经历它。

当您使用setAttribute("class", "green");时,您将“wasd”类替换为“green”

如果您添加一个类而不是使用ele.classList.add(class)

替换当前类,这将有效

this graph

答案 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>