循环遍历时无法编辑classList

时间:2017-03-27 21:12:45

标签: javascript loops dom

我有一个像这样的元素:

<span class="util bg-color-yellow tooltip bg-color-red"></span>

我想删除所有以“bg-color-”开头的类,所以我只需循环遍历所有类,然后删除匹配的类:

var element = document.getElement......;

var elementClasses = element.classList;


for( var i = 0, l = elementClasses.length; i < l; i++ )
{
    var className = elementClasses[i];

    // console.log(i);
    // console.log(name);

    if( className.startsWith('bg-color-') )
    {
        element.classList.remove(className);
    }

    console.log('elementClasses contain :');
    console.log(elementClasses);
}

当它与'bg-color-'类匹配时,它会成功删除类名,但它也会编辑变量elementClasses,就像它是对element.classList的引用一样,即使它是变量(副本)。

第一圈:

elementClasses = [ util bg-color-yellow tooltip bg-color-red ]

第二循环:

elementClasses = [ util bg-color-yellow tooltip bg-color-red ]

第3次循环:

elementClasses = [ util tooltip bg-color-red ]

出现了问题elementClasses在修改elemnt.classList的同时进行了修改!

  • 怎么可能?
  • 有效elementClasseselement.classList的一种参考吗?
  • 每次elementClasses修改后,element.classList是否自行重新创建了它?

非常感谢! :)

3 个答案:

答案 0 :(得分:2)

您已经确定了导致问​​题的原因,这很好。现在为解决方案:

// ES6
[...elementClasses].forEach((className, i) => {
// OR ES5
Array.prototype.slice.call(elementClasses).forEach(function (className, i) {

    // console.log(i);
    // console.log(className);

    if( className.startsWith('bg-color-') )
    {
        element.classList.remove(className);
    }

    console.log('elementClasses contain :');
    console.log(elementClasses);
});

使用这些方法之一,classList被浅层复制,以确保在修改数组时不跳过条目。

要回答您的其他问题,原始代码中的elementClasses确实是element.classList的引用,这就是为什么当其中一个被修改时它们都被修改的原因。

在我的ES6建议中,[...elementClasses]使用点差运算符将浅层副本复制到原始Array,而ES5方法在原始slice()上调用element.classList制作一份浅色的副本。

现在进行演示:

&#13;
&#13;
var element = document.querySelector('span');
var elementClasses = element.classList;

// ES6
// [...elementClasses].forEach((className, i) => {
// OR ES5
Array.prototype.slice.call(elementClasses).forEach(function (className, i) {

    console.log(i);
    console.log(className);

    if( className.startsWith('bg-color-') )
    {
        element.classList.remove(className);
    }

    console.log('elementClasses contain :');
    console.log(JSON.stringify(elementClasses));
});
&#13;
<span class="util bg-color-yellow tooltip bg-color-red"></span>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

在您的实施中,driver.manage().window().maximize();实际上并不是elementClass的副本。它是对同一对象的引用。要复制对象,请考虑使用element.classList

看到这个问题: Copying array by value in JavaScript

答案 2 :(得分:0)

请参阅这篇文章,这解释了当您使用'='符号

时javascript如何复制变量的答案

Copy a variable's value into another