【问题标题】:How to remove a class from elements in pure JavaScript?如何从纯 JavaScript 中的元素中删除一个类?
【发布时间】:2014-04-11 19:33:14
【问题描述】:

我想知道如何选择类名为“widget”和“hover”的所有元素,然后从这些元素中删除类“hover”。

我有以下 JavaScript 代码,它选择所有具有类“widget”和“hover”的元素:

var elements = document.getElementsByClassName('widget hover');
console.log(elements);

这似乎工作并输出类似这样的内容(没有错误):

[div#.widget... 

问题是,如果我尝试删除“悬停”类,我会收到错误:

var elements = document.getElementsByClassName('widget hover');
console.log(elements);
elements.classList.remove("hover");

这个输出:

[item: function]
length: 0
Uncaught TypeError: Cannot call method 'remove' of undefined 

谁能告诉我我做错了什么?


请注意,我有它在 jQuery 中工作:

$('.widget.hover').removeClass('hover');

...但我正在寻找纯 JavaScript 的解决方案。

【问题讨论】:

  • 请注意 classList 在 IE
  • 我不关心 IE8 及以下版本,但 IE9 有什么用?

标签: javascript getelementsbyclassname


【解决方案1】:
var elems = document.querySelectorAll(".widget.hover");

[].forEach.call(elems, function(el) {
    el.classList.remove("hover");
});

您可以将.classList 修补到IE9 中。否则,您需要修改.className

var elems = document.querySelectorAll(".widget.hover");

[].forEach.call(elems, function(el) {
    el.className = el.className.replace(/\bhover\b/, "");
});

.forEach() 也需要 IE8 的补丁,但这很常见。

【讨论】:

  • @Andrew:如果类可能包含非字母数字字符,.className.replace() 应该更复杂一些。例如,如果一个类可能是hover-me,则hover 部分可能与正则表达式匹配。不确定您需要多广泛的解决方案。
  • 因为你是第一个回答的,所以我给你。
  • @Andrew:我不是第一个,但另一个答案确实需要修复。
【解决方案2】:

查找元素:

var elements = document.getElementsByClassName('widget hover');

由于 elements 是一个 live 数组并反映了所有 dom 更改,您可以使用简单的 while 循环删除所有 hover 类:

while(elements.length > 0){
    elements[0].classList.remove('hover');
}

【讨论】:

    【解决方案3】:

    现在是 2022 年...保持简单,只使用 es6

    时代变了,现在最简洁、最易读的方法是:

    Array.from(document.querySelectorAll('.widget.hover')).forEach((el) => el.classList.remove('hover'));
    

    如果你不支持箭头函数,那么就这样转换它:

    Array.from(document.querySelectorAll('.widget.hover')).forEach(function(el) { 
        el.classList.remove('hover');
    });
    

    此外,如果您需要支持非常旧的浏览器,请使用 polyfil 来代替 forEachArray.from,然后继续您的生活。

    【讨论】:

    • querySelectorAll 不是更现代的方式吗?
    • @Qasim 我应该强调我的重点不是如何获取元素,而是如何使用Array.fromforEach 循环和删除它们
    • 你可以搭上 Array.from: (document.querySelectorAll("div")).forEach((el) => el.classList.remove("selected"));
    • 我试过不使用“Array.from”,它似乎也可以工作,如果使用“Array.from”有什么特殊目的,请告诉我。
    • @Danie - 这仍然有效,两者之间的区别在于一个引用 NodeList[]Array.from 引用 Array[]see this writeup for more information
    【解决方案4】:

    Elements 是一个 DOM 对象数组。你应该这样做:

    for (var i = 0; i < elements.length; i++) {
       elements[i].classList.remove('hover');
    }
    

    枚举元素集合并为集合中的每个元素调用remove 方法

    【讨论】:

    • 这非常有效。我没有意识到元素会是一个数组,所以这很有意义。有没有更快的东西不必重新遍历整个数组?
    • 我相信没有比这更快的了。 JQuery 可能应该做类似的事情。但是不要担心速度,您必须拥有数千(如果不是百万)元素才能看到性能问题
    • 要考虑的一点是,在问题中,.getElementsByClassName 被用于获取元素。因为您要删除用于获取的类之一,所以该元素将从elements 列表中删除,这意味着该列表将被重新索引,并且您最终会跳过一些元素。反向迭代更安全。
    • 基于@cookiemonster 的观点,这里是递归版本:for (var i = elements.length-1; i &gt; -1; i--) {}
    • @MattBaker 你的版本可以工作,但不是因为它是递归版本,它只是因为 getElementsByClassName 返回“live”数组所以当你从 0-up 删除类时,它们会从“live”数组中消失.当您隐藏第 0 项时,第 1 项移动到第 0 位,但您从第 1 项继续循环,从而将第 0 项留在类中。从头到尾解决了这个问题。
    【解决方案5】:

    对于 ES6,这可以通过 one liners 以几种方式完成,您可以使用扩展运算符 ... 创建一个元素数组,并使用 map 删除该类运营商:

    querySelectorAll:

    [...document.querySelectorAll('.widget')].map(x => x.classList.remove('hover'));
    

    getElementsByClassName:

    [...document.getElementsByClassName('widget')].map(x => x.classList.remove('hover'));
    

    对于querySelectorAll,请注意使用.widget 而不是widget。扩展运算符的替代方法是使用Array.from,例如:

    Array.from(document.querySelectorAll('.widget')).map(x => x.classList.remove('hover'));
    

    【讨论】:

      【解决方案6】:

      这可能会有所帮助

      let allElements = Array.from(document.querySelectorAll('.widget.hover'))
      for (let element of allElements) {
        element.classList.remove('hover')
      }
      

      【讨论】:

        【解决方案7】:

        鉴于为我工作。

        document.querySelectorAll(".widget.hover").forEach(obj=>obj.classList.remove("hover"));
        

        【讨论】:

        • 欢迎来到 Stack Overflow!为了保持高质量的答案,请避免仅是代码的答案并添加解释。
        【解决方案8】:
        var elems = document.querySelectorAll(".widget.hover");
        
         for(let elem of elems){
                elem.classList.remove('hover');
                }
        

        【讨论】:

          【解决方案9】:

          我使用一个简单的方法。 如果您始终在所需的循环数中处理 [0],则可以将该处理应用于所有循环。

          HTMLCollection(elements) 是实时变化的,所以把长度放在一个变量中。 (l = element.length)

          for(var elements=document.getElementsByClassName('widget hover'),i=0,l=elements.length; l>i; i++) {
            elements[0].classList.remove("hover");
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-19
            • 2011-11-19
            • 2017-01-23
            • 1970-01-01
            • 1970-01-01
            • 2016-05-12
            相关资源
            最近更新 更多