【问题标题】:What is the "hasClass" function with plain JavaScript?什么是纯 JavaScript 的“hasClass”函数?
【发布时间】:2011-07-02 10:00:00
【问题描述】:

你如何用普通的 JavaScript 处理 jQuery 的 hasClass?例如,

<body class="foo thatClass bar">

询问&lt;body&gt; 是否有thatClass 的JavaScript 方法是什么?

【问题讨论】:

  • 我想你必须解析 class 属性(在多个类的情况下将有多个类名以随机顺序由空格分隔)并检查你的类名是否在其中。不是很困难,但如果不是为了学习目的,仍然很不方便:)
  • 不知道我是否迟到了,但提供 jQuery 函数替代品的好网站是 youmightnotneedjquery.com

标签: javascript dom


【解决方案1】:

这个 'hasClass' 函数适用于 IE8+、FireFox 和 Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}

[2021 年 1 月更新] 更好的方法:

hasClass = (el, cls) => {
  [...el.classList].includes(cls); //cls without dot
};

【讨论】:

  • 更好:[...el.classList].includes(cls); //cls 没有点
  • 我认为您的意思是 [...el.classList].contains(cls); 用于 2021 年的更新,对吧?
  • Node.contains 用于子节点。使用 [... ] 它将 DOMTokenList 转换为节点类的数组。要搜索我使用的数组,包括
【解决方案2】:

Element.matches()

您可以在纯 JavaScript 中使用 element.matches('.example'),而不是 jQuery 中的 $(element).hasClass('example')

if (element.matches('.example')) {
  // Element has example class ...
}

View Browser Compatibility

【讨论】:

【解决方案3】:

只需使用classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

classList的其他用途:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

浏览器支持:

  • Chrome 8.0
  • 火狐3.6
  • IE 10
  • Opera 11.50
  • Safari 5.1

classList Browser Support

【讨论】:

  • IE8 不支持此功能。 IE8 可以将.classList 检索为字符串,但它不会识别更现代的方法,例如.classList.contains()
  • @iono 在来自 MDN 的 Element.classList 实现描述中,有一个 shim 将对此行为的支持扩展到 IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
  • 我同意@AlexanderWigmore,这非常有用且简单。
  • 这应该是自 2020 年以来可以接受的答案。因为没有人再谈论 IE8 / WinXP。
  • 同意。 .. IE8 已经死了。 IE一般都死了。这应该是前进的方向。
【解决方案4】:
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}

【讨论】:

    【解决方案5】:

    使用类似的东西:

    Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
    

    【讨论】:

    • 这不等于myHTMLSelector.classList.indexOf('the-class')吗?最后你不也想要&gt;=0吗?
    • 如果classListcontains 方法,那么使用[].indexOf 有什么意义?
    • @Teepeemm 没有。 myHTMLSelector.classList.indexOf('the-class') 返回 myHTMLSelector.classList.indexOf is not a function 的错误,因为 myHTMLSelector.classList 不是数组。但我想当使用Array.prototype 调用它时会发生一些转换。这可能支持旧版浏览器,虽然contains 有很好的支持。
    【解决方案6】:

    hasClass 函数:

    HTMLElement.prototype.hasClass = function(cls) {
        var i;
        var classes = this.className.split(" ");
        for(i = 0; i < classes.length; i++) {
            if(classes[i] == cls) {
                return true;
            }
        }
        return false;
    };
    

    添加类函数:

    HTMLElement.prototype.addClass = function(add) {
        if (!this.hasClass(add)){
            this.className = (this.className + " " + add).trim();
        }
    };
    

    removeClass 函数:

    HTMLElement.prototype.removeClass = function(remove) {
        var newClassName = "";
        var i;
        var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
        for(i = 0; i < classes.length; i++) {
            if(classes[i] !== remove) {
                newClassName += classes[i] + " ";
            }
        }
        this.className = newClassName.trim();
    };
    

    【讨论】:

      【解决方案7】:

      最有效的一种衬里

      • 返回布尔值(与 Orbling 的答案相反)
      • 在具有class="thisClass-suffix" 的元素上搜索thisClass 时不会返回误报。
      • 兼容至少 IE6 的所有浏览器

      function hasClass( target, className ) {
          return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
      }
      

      【讨论】:

        【解决方案8】:

        我使用一个简单/最小的解决方案,单行,跨浏览器,并且也适用于旧版浏览器:

        /\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'
        

        这种方法很棒,因为不需要polyfills,如果你将它们用于classList,它在性能方面会好得多。至少对我来说。

        更新:我制作了一个小型 polyfill,这是我现在使用的全方位解决方案:

        function hasClass(element,testClass){
          if ('classList' in element) { return element.classList.contains(testClass);
        } else { return new Regexp(testClass).exec(element.className); } // this is better
        
        //} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
          return false;
        }
        

        有关其他类操作,请参阅完整文件here

        【讨论】:

        • 这个行程会不会超过notmyClassHere的班级?
        • 您也可以询问您的班级是否也没有!/myClass/.test(document.body.className),请注意! 符号。
        • 我不是在谈论否定这个问题。我认为如果类名是 thisIsmyClassHere,您的函数将不正确地返回 true。
        • 我只是猜测这就是您要问的问题,并不完全了解您需要什么,但是您尝试过它并未能按应有的方式返回真/假吗?
        • 这并不完美,因为它不是子字符串证明。例如。当 document.body.className = 'myClass123' 时,则 /myClass/.test(document.body.className) 返回 true...
        【解决方案9】:

        您如何看待这种方法?

        <body class="thatClass anotherClass"> </body>
        
        var bodyClasses = document.querySelector('body').className;
        var myClass = new RegExp("thatClass");
        var trueOrFalse = myClass.test( bodyClasses );
        

        https://jsfiddle.net/5sv30bhe/

        【讨论】:

        • 我认为您正在混合变量名称(active===myClass?)。但是这种方法不会对class="nothatClassIsnt" 产生误报吗?
        【解决方案10】:

        一个很好的解决方案是使用 classList 和 contains。

        我是这样做的:

        ... for ( var i = 0; i < container.length; i++ ) {
                if ( container[i].classList.contains('half_width') ) { ...
        

        所以你需要你的元素并检查类列表。如果其中一个类与您搜索的类相同,则返回 true,否则返回 false!

        【讨论】:

          【解决方案11】:

          // 1. Use if for see that classes:
          
          if (document.querySelector(".section-name").classList.contains("section-filter")) {
            alert("Grid section");
            // code...
          }
          <!--2. Add a class in the .html:-->
          
          <div class="section-name section-filter">...</div>

          【讨论】:

          • @greg_diesel:不要阻止答案!常见问题的新解决方案非常受欢迎。
          • @Raveren 虽然欢迎旧问题的新解决方案,但这个特殊的答案并没有带来任何新的东西。它只会增加这个问题的噪音。
          • @raveren 这不是一个新的解决方案,它与this answer 相同,但信息较少。
          【解决方案12】:

          以上所有答案都非常好,但这是我创建的一个简单的小功能。它工作得很好。

          function hasClass(el, cn){
              var classes = el.classList;
              for(var j = 0; j < classes.length; j++){
                  if(classes[j] == cn){
                      return true;
                  }
              }
          }
          

          【讨论】:

          • 如果classListcontains 方法,那么迭代有什么意义?
          【解决方案13】:

          您可以检查element.className 是否与/\bthatClass\b/ 匹配。
          \b 是否匹配分词符。

          或者,你可以使用jQuery自己的实现:

          var className = " " + selector + " ";
          if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 
          

          要回答您更一般的问题,您可以查看 github 上的 jQuery source codehasClass specifically in this source viewer 的源代码。

          【讨论】:

          • +1 用于 jQuery 实现(用于查找(这是正确的英语吗?)rclass 实际上是什么;))
          • 不会\b 匹配“thatClass-anotherClass”?
          • 只是为了完整性:最近版本中的 rclass 是 "/[\n\t\r]/g" (\r 添加)
          • @FelixSchwarz 是对的,在当前的 jQuery 中,正则表达式已更新为 /[\t\r\n\f]/g。另外值得一提的是,/\bclass\b/ 对于带有- 减号的类名可能会失败(除了它工作得很好),这就是为什么 jQuery 的实现更好、更可靠的原因。例如:/\bbig\b/.test('big-text') 返回 true 而不是预期的 false。
          • 当最初的问题是要求非 jQuery 实现时,这个讨论是如何变成 jQuery 的?
          【解决方案14】:

          存储正在使用的类的属性是className

          所以你可以说:

          if (document.body.className.match(/\bmyclass\b/)) {
              ....
          }
          

          如果你想要一个展示 jQuery 如何做所有事情的位置,我建议:

          http://code.jquery.com/jquery-1.5.js

          【讨论】:

          • 优秀。 match 属性又派上用场了! jQuery 真的做的事情比 JavaScript 做的还多吗?!如果没有,jQuery 只是一个不必要的速记。
          • 这也匹配myclass-something,因为\b 匹配连字符。
          • @animaacija 所有 javascript 库/插件基本上都是 javascript 简写,因为它们是用 javascript 构建的。事情是:速记总是必要的。永远不要重新发明轮子。
          • 我认为 classList.contains('className') 是比这更好的解决方案。避免泛化 Edwin。你应该停止使用“总是”和“从不”这样的字眼
          猜你喜欢
          • 1970-01-01
          • 2020-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-04
          • 2016-11-15
          • 2010-11-07
          相关资源
          最近更新 更多