数组 forEach 跳过奇数索引

3
需要移除那些带有前缀 nf- 的元素的某些类,并保留其他所有类。元素可能具有一个或多个带有该前缀的类。
<div class="custom-nf">
  <div class="input nf-input-outer nf-validation">
    <div class="nf-container">
      <div class="nf-outer nf-outer-input nf-outer-validation">
        <div class="nf-middle">
          <div class="nf-inner">
            <label for="dummy" class="nf-label"></label>
            <input id="dummy" type="text" class="nf-input"></div>
        </div>
      </div>
    </div>
  </div>
</div>

我有下面的脚本,它可以获取所有类名前缀为 nf- 的元素,然后针对每个元素查看 classList 属性,对于每个类,判断当前类字符串是否与正则表达式中定义的前缀匹配。如果是,则从元素中删除该类。
(function(){
  // get elements with nf- prefix class
  var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
  // each element found
  Array.prototype.forEach.call(nfClasses, function(element){
    // each class per element with classList
    Array.prototype.forEach.call(element.classList, function(el){
      // only for classes that match prefix nf-
      if (el == el.match(/^nf-.*/g)) {
        // remove nf- class from the element
        element.classList.remove(el);
      }
    });
  });
})();

现在代码看起来运行良好,并且可以删除以特定前缀开头的类,但是内部的forEach部分无法删除classList数组中出现为奇数索引的类。以下是代码运行后HTML的样子:

<div class="custom-nf">
  <div class="input nf-validation">
    <div class="">
      <div class="nf-outer-input">
        <div class="">
          <div class="">
            <label for="dummy" class=""></label>
            <input id="dummy" type="text" class=""></div>
        </div>
      </div>
    </div>
  </div>
</div>

运行代码将减少其余类,以此类推,直到所有类都消失,但这并不实际,且带有前缀的元素可能具有未知数量的类。
如果您想查看,我已经准备好JSFiddle
为什么内部forEach跳过奇数索引,如何纠正它?

1
我不确定,所以我不会把这个作为答案,但是我猜测从回调函数内部修改element.classList会改变指针,因此跳过刚刚删除的元素旁边的元素。 - Matteo Tassinari
1个回答

2

在回调函数内修改element.classList会改变数组的索引,因此跳过刚刚删除的元素旁边的元素。

只需更改外部回调函数:

(function() {
  // get elements with nf- prefix class
  var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
  // each element found
  Array.prototype.forEach.call(nfClasses, function(element) {
    // here you gather class names to remove
    var toRemove = [];

    // each class per element with classList
    Array.prototype.forEach.call(element.classList, function(el) {
      // only for classes that match prefix nf-
      if (el.match(/^nf-.*/)) {
        // remove nf- class from the element
        toRemove.push(el);
      }
    });

    // now actually remove those classes
    toRemove.forEach(function(el) {
      element.classList.remove(el);
    });
  });
})();

https://jsfiddle.net/fcu1ypds/5/ 查看它的实际效果。


移除后数组变短这一点说出来后似乎很显而易见,完全有道理。我猜想在每个数组迭代完成之前,数组长度不会受到影响,会在迭代结束后受到影响,所以保存索引直到所有循环都结束。非常感谢,谢谢! - Ash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接