什么是纯 JavaScript 的“hasClass”函数?

Posted

技术标签:

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

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

<body class="foo thatClass bar">

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

【问题讨论】:

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

【讨论】:

hasClass drop-in w/ es6...hasClass = (el, name) =&gt; el.matches('.'+name) ? 1 : 0 应该是最佳答案。 确实最短,但可能更慢 (measurethat.net/Benchmarks/Show/7742/0/…)。【参考方案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(/\s2,/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 code 或 hasClass 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。你应该停止使用“总是”和“从不”这样的字眼

以上是关于什么是纯 JavaScript 的“hasClass”函数?的主要内容,如果未能解决你的问题,请参考以下文章

我使用的是纯 JavaScript,但我继续收到以“不是函数”结尾的错误。如何做到这一点,以便我可以检测单词并做出相应的回复?

什么是纯函数

JavaScript 需要了解的高级的知识点

什么是纯函数?

什么是纯函数?

javascript进阶笔记