使用JavaScript从每个元素中删除隐藏的类

sha*_*ain 1 javascript arrays

我试图通过JavaScript点击元素中的所有隐藏类.这是我用来尝试这样做的虚拟代码:

    <style>
    .hidden {display:none;}
    </style>
    

    <div>Value 1</div>
    <div class="hidden">Value 2</div>
    <div class="hidden">Value 3</div>
    <div class="hidden">Value 4</div>
    
    
    <button onclick="removeHidden()">Show All</button>
    
    
    <script>
    function removeHidden()
    {
        var hidden = document.getElementsByClassName("hidden");
        for(var i=0; i<hidden.length; i++)
        {
            hidden[i].classList.remove("hidden");
        }
    }
    </script>
Run Code Online (Sandbox Code Playgroud)

单击按钮时,我希望删除所有类"隐藏",但奇怪的是,它会从第二个div和第四个div中删除隐藏的类,但会跳过第三个.

我得到的结果是:

Value 1
Value 2
Value 4
Run Code Online (Sandbox Code Playgroud)

知道为什么那是因为我真的不明白吗?

我也尝试过这段代码但结果相同:

var els = document.getElementsByClassName("hidden");

Array.prototype.forEach.call(els, function(el) {
    el.ClassList.remove("hidden");
});
Run Code Online (Sandbox Code Playgroud)

Sco*_*cus 5

问题是getElementsByClassName()返回"实时"节点列表,该列表是在您引用列表时随时更新的列表.这可确保您始终获得最新的元素引用.这是一种昂贵的结构,实际上仅适用于需要时的罕见用例.

每次代码引用hidden变量时,都会重新扫描DOM以查找具有hidden该类的元素,并在开始删除该类之后,列表的长度缩小一.这是因为这一变化length导致一个项目被跳过.

getElementsByClassName()在此处正确使用,请先从最后一个元素中删除该类,然后向后移动到第一个元素.这可确保随着节点列表的长度缩小,您不会跳过任何节点.

<style>
    .hidden {display:none;}
</style>
    
    <div>Value 1</div>
    <div class="hidden">Value 2</div>
    <div class="hidden">Value 3</div>
    <div class="hidden">Value 4</div>
    
    
    <button onclick="removeHidden()">Show All</button>
          
    <script>
    function removeHidden()
    {
        var hidden = document.getElementsByClassName("hidden");
        for(var i = hidden.length-1; i > -1; i--)
        {
            hidden[i].classList.remove("hidden");
        }
    }
    </script>
Run Code Online (Sandbox Code Playgroud)

但是,因为实时节点列表会导致性能损失,所以一般情况下不要使用它们.相反,使用静态节点列表,您可以使用更现代,更灵活的方式获得静态节点列表.querySelectorAll().此外,如果我们将返回的静态节点列表.querySelectorAll()转换为Array,我们可以使用Array API对其进行迭代.forEach(),从而无需索引器.

<style>
    .hidden {display:none;}
</style>
    

    <div>Value 1</div>
    <div class="hidden">Value 2</div>
    <div class="hidden">Value 3</div>
    <div class="hidden">Value 4</div>        
    
    <button onclick="removeHidden()">Show All</button>
            
    <script>
    function removeHidden()
    {
        // Get all the elements that match the selector into an Array
        var hidden = Array.prototype.slice.call(document.querySelectorAll(".hidden"));
        
        // Now we can loop using the Array API
        hidden.forEach(function(item){
            item.classList.remove("hidden");
        });
    }
    </script>
Run Code Online (Sandbox Code Playgroud)