检查元素是否包含JavaScript中的类?


585

使用普通的JavaScript(不是jQuery),是否可以检查元素是否包含类?

目前,我正在这样做:

var test = document.getElementById("test");
var testClass = test.className;

switch (testClass) {
  case "class1":
    test.innerHTML = "I have class1";
    break;
  case "class2":
    test.innerHTML = "I have class2";
    break;
  case "class3":
    test.innerHTML = "I have class3";
    break;
  case "class4":
    test.innerHTML = "I have class4";
    break;
  default:
    test.innerHTML = "";
}
<div id="test" class="class1"></div>

问题是,如果我将HTML更改为此...

<div id="test" class="class1 class5"></div>

...不再存在完全匹配的内容,因此我得到的默认输出为none("")。但我还是想输出为I have class1,因为<div>包含.class1类。


5
element.classList.contains(cls)
罗尼·罗斯顿

Answers:


1034

使用方法:element.classList .contains

element.classList.contains(class);

这适用于所有当前浏览器,并且也有polyfill支持较旧的浏览器。


另外,如果您使用的是较旧的浏览器,并且不想使用polyfill对其进行修复,则使用indexOf正确,但是您需要对其进行一些调整:

function hasClass(element, className) {
    return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}

否则,true如果您要查找的班级是另一个班级名称的一部分,您也将获得。

演示

jQuery使用类似(如果不相同)的方法。


应用于示例:

由于这不能与switch语句一起使用,因此可以使用以下代码实现相同的效果:

var test = document.getElementById("test"),
    classes = ['class1', 'class2', 'class3', 'class4'];

test.innerHTML = "";

for(var i = 0, j = classes.length; i < j; i++) {
    if(hasClass(test, classes[i])) {
        test.innerHTML = "I have " + classes[i];
        break;
    }
}

它也较少冗余;)


太棒了,但是如何将其与switch语句结合使用,以便可以根据div包含的类来更改输出?
daGUY 2011年

@daGUY:无论如何,您想使用switch语句做什么?例如,第二个div有两个类,但仅I have class1在您使用时输出break。如果要输出元素具有的每个类,则可以采用className并将其分割在空白处。或您的实际目标是什么?
Felix Kling,

@Felix Kling:我需要div的innerHTML在四个不同的字符串之间进行切换,具体取决于它包含的类。我只是使用“我有class1”等作为示例-实际的字符串都是不同的。我一次只会显示一个字符串,而不会合并任何字符串(因此在每种情况下都会中断)。我只希望即使匹配的类是div上多个类之一,它仍然可以工作。
daGUY 2011年

@Felix Kling:做到了,非常感谢!实际上,我不是在输出类的名称,而是输出四个完全不同的字符串之一,因此我用一些IF / ELSE IF语句对它进行了少许修改以处理每个字符串。完美的作品。
daGUY 2011年

1
为何在前后添加空格有特定的原因?
Ced 2016年


49

在现代浏览器中,您可以使用以下contains方法Element.classList

testElement.classList.contains(className)

演示版

var testElement = document.getElementById('test');

console.log({
    'main' : testElement.classList.contains('main'),
    'cont' : testElement.classList.contains('cont'),
    'content' : testElement.classList.contains('content'),
    'main-cont' : testElement.classList.contains('main-cont'),
    'main-content' : testElement.classList.contains('main-content')
});
<div id="test" class="main main-content content"></div>


支持的浏览器

在此处输入图片说明

(来自CanIUse.com


Polyfill

如果你想使用Element.classList,但你也想支持旧的浏览器,可以考虑使用这种填充工具礼灰色


10

由于他想使用switch(),所以我很惊讶还没有人提出这一点:

var test = document.getElementById("test");
var testClasses = test.className.split(" ");
test.innerHTML = "";
for(var i=0; i<testClasses.length; i++) {
    switch(testClasses[i]) {
        case "class1": test.innerHTML += "I have class1<br/>"; break;
        case "class2": test.innerHTML += "I have class2<br/>"; break;
        case "class3": test.innerHTML += "I have class3<br/>"; break;
        case "class4": test.innerHTML += "I have class4<br/>"; break;
        default: test.innerHTML += "(unknown class:" + testClasses[i] + ")<br/>";
    }
}

1
我只是想知道同一件事,但是,是的,这与原始问题最接近!
Silver Ringvee '16

8

Element.matches()

element.matches(selectorString)

根据MDN网络文档

如果元素将由指定的选择器字符串选择,则该Element.matches()方法返回;true否则返回false。否则,返回false

因此,可以Element.matches()用来确定一个元素是否包含一个类。

const element = document.querySelector('#example');

console.log(element.matches('.foo')); // true
<div id="example" class="foo bar"></div>

查看浏览器兼容性


7

如果您尝试检查是否包含一个类的元素,而不使用jQuery,这是一个小片段。

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

这说明了一个事实,即元素可能包含多个用空格分隔的类名。

要么


您也可以将此功能分配给元素原型。

Element.prototype.hasClass = function(className) {
    return this.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(this.className);
};

并像这样触发它(非常类似于jQuery的.hasClass()功能):

document.getElementById('MyDiv').hasClass('active');

我更喜欢这种解决方案。它避免了类名与另一个类部分匹配的问题,并且不需要polyfill在IE中工作。
scoota269

5

简化的单线:1

function hasClassName(classname,id) {
 return  String ( ( document.getElementById(id)||{} ) .className )
         .split(/\s/)
         .indexOf(classname) >= 0;
}

indexOfIE(当然)不支持数组 1。网上有很多猴子补丁。


1
单词边界的问题是类名称的某些有效字符(例如)-被视为单词边界。例如寻找,foo而类就是foo-bar收益true
菲利克斯·克林

你是对的。删除了原来的内容,添加了另一种方法。仍然是一个班轮。
KooiInc 2011年

5

这有点旧,但是也许有人会对我的解决方案有所帮助:

// Fix IE's indexOf Array
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement) {
        if (this == null) throw new TypeError();
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) return -1;
        var n = 0;
        if (arguments.length > 0) {
            n = Number(arguments[1]);
            if (n != n) n = 0;
            else if (n != 0 && n != Infinity && n != -Infinity) n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
        if (n >= len) return -1;
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) if (k in t && t[k] === searchElement) return k;
        return -1;
    }
}
// add hasClass support
if (!Element.prototype.hasClass) {
    Element.prototype.hasClass = function (classname) {
        if (this == null) throw new TypeError();
        return this.className.split(' ').indexOf(classname) === -1 ? false : true;
    }
}

使用:'element.hasClass('classname');
Dementic

为什么使用t.length >>> 0?据我所知,如果您使用'0'则是noop,对吗?
Vitor Canova

太简单了 为什么不使用正则表达式而不重新发明轮子呢?你可以只使用/^class_name_you_are_searching_for$/.test(myElement.className)
PQSK调辨

1
我写得太快了。只是不要过分复杂化我的正则表达式这将是/\s*class_name_you_are_searching_for\s*/.test(myElement.className)
PQSK调辨

@pqsk-我编写了自己的库以供将来使用。这只是添加到我的堆栈中。当然也可以使用其他解决方案,这只是我的首选方式
Dementic,2015年

4

className只是一个字符串,因此您可以使用常规的indexOf函数查看类列表是否包含另一个字符串。


1
class上例中的类测试怎么样?
菲利克斯·克林

6
根据经验,此方法可能会很冒险:当您在具有类foo的元素上查找该类时,它将返回true foobar
Zirak

2
当然,您只是知道要测试的内容。Felix的代码通过使用空格作为分隔符可以很好地工作。
大卫,

无法解释类名的嵌套实例。示例:在类名“ frontend”中可以找到“ end”。
Anthony Rutledge,2016年

4

我知道有很多答案,但是大多数答案都是针对附加功能和附加类的。这是我个人使用的;更简洁,更少的代码行!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}

1
当搜索部分匹配的类名时,此方法可能返回假阳性-例如<body class="category-page">document.body.className.match('page')-将匹配,但没有page附加到该元素的类
hooblei

可以使用来解决\b,例如/\bpage\b/g,因为它是正则表达式(注意:必须使用/ /g)。
Andrew

2

这是一个不区分大小写的简单解决方案:

function hasClass(element, classNameToTestFor) {
    var classNames = element.className.split(' ');
    for (var i = 0; i < classNames.length; i++) {
        if (classNames[i].toLowerCase() == classNameToTestFor.toLowerCase()) {
            return true;
        }
    }
    return false;
}

2

如果元素只有一个类名,则可以通过获取class属性来快速检查它。其他答案更加健壮,但是肯定有用例。

if ( element.getAttribute('class') === 'classname' ) {

}

2

我创建了一个原型方法classList,如果可能的话,使用其他方法indexOf

Element.prototype.hasClass = Element.prototype.hasClass || 
  function(classArr){
    var hasClass = 0,
        className = this.getAttribute('class');
  
    if( this == null || !classArr || !className ) return false;
  
    if( !(classArr instanceof Array) )
      classArr = classArr.split(' ');

    for( var i in classArr )
      // this.classList.contains(classArr[i]) // for modern browsers
      if( className.split(classArr[i]).length > 1 )  
          hasClass++;

    return hasClass == classArr.length;
};


///////////////////////////////
// TESTS (see browser's console when inspecting the output)

var elm1 = document.querySelector('p');
var elm2 = document.querySelector('b');
var elm3 = elm1.firstChild; // textNode
var elm4 = document.querySelector('text'); // SVG text

console.log( elm1, ' has class "a": ', elm1.hasClass('a') );
console.log( elm1, ' has class "b": ', elm1.hasClass('b') );
console.log( elm1, ' has class "c": ', elm1.hasClass('c') );
console.log( elm1, ' has class "d": ', elm1.hasClass('d') );
console.log( elm1, ' has class "a c": ', elm1.hasClass('a c') );
console.log( elm1, ' has class "a d": ', elm1.hasClass('a d') );
console.log( elm1, ' has class "": ', elm1.hasClass('') );

console.log( elm2, ' has class "a": ', elm2.hasClass('a') );

// console.log( elm3, ' has class "a": ', elm3.hasClass('a') );

console.log( elm4, ' has class "a": ', elm4.hasClass('a') );
<p class='a b c'>This is a <b>test</b> string</p>
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="50px">
    <text x="10" y="20" class='a'>SVG Text Example</text>
</svg>

测试页


为什么要使用classlist而不是e.className的索引是有原因的?好像性能不太好
Ced 2016年

@Ced-好吧,如果您不为它们的类测试数千个元素,那么perf无关紧要(将来可能会在浏览器中对其进行重构)。使用起来更优雅,因为代码描述了其功能,但是最重要的是,不要紧,无论您想要做什么:)
vsync

1
  1. Felix的添加空格以在className和要搜索的字符串后缀的技巧是确定元素是否具有类的正确方法。

  2. 要根据类具有不同的行为,可以在映射内使用函数引用或函数:

    function fn1(element){ /* code for element with class1 */ }
    
    function fn2(element){ /* code for element with class2 */ }
    
    function fn2(element){ /* code for element with class3 */ }
    
    var fns={'class1': fn1, 'class2': fn2, 'class3': fn3};
    
    for(var i in fns) {
        if(hasClass(test, i)) {
            fns[i](test);
        }
    }
    • for(var in in fns)遍历fns映射中的键。
    • 在fnsi之后不间断允许代码在存在匹配项时执行-因此,如果元素具有fi,class1和class2,则将同时执行fn1和fn2。
    • 这种方法的优点是,为每个类执行的代码是任意的,就像switch语句中的代码一样。在您的示例中,所有案例都执行了类似的操作,但是明天您可能需要针对每种情况执行不同的操作。
    • 您可以通过让状态变量告诉您​​是否在循环中找到匹配项来模拟默认情况。


1

这有点差,但是如果您有触发切换的事件,则可以不使用类:

<div id="classOne1"></div>
<div id="classOne2"></div>
<div id="classTwo3"></div>

你可以做

$('body').click( function() {

    switch ( this.id.replace(/[0-9]/g, '') ) {
        case 'classOne': this.innerHTML = "I have classOne"; break;
        case 'classTwo': this.innerHTML = "I have classTwo"; break;
        default: this.innerHTML = "";
    }

});

.replace(/[0-9]/g, '') 从中删除数字 id

它有点hacky,但适用于长时间切换而没有额外的功能或循环


1

请参阅此Codepen链接,以使用vanilla JavaScript〜更快,更轻松地检查元素是否具有特定类的元素!

hasClass(香草JS)

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

1

IE8 +支持此功能。

首先,我们检查是否classList存在,可以使用containsIE10 +支持的方法。如果我们使用的是IE9或8,它会退回到使用正则表达式,它虽然效率不高,但却是简洁的polyfill。

if (el.classList) {
  el.classList.contains(className);
} else {
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}

另外,如果您正在使用babel进行编译,则可以简单地使用: el.classList.contains(className);


0

试试这个:

document.getElementsByClassName = function(cl) {
   var retnode = [];
   var myclass = new RegExp('\\b'+cl+'\\b');
   var elem = this.getElementsByTagName('*');
   for (var i = 0; i < elem.length; i++) {
       var classes = elem[i].className;
       if (myclass.test(classes)) retnode.push(elem[i]);
   }
    return retnode;
};

1
小心边界这个词。如果您有一个类foo-bar并搜索,它也将匹配true foo
菲利克斯·克林

1
嗨,吉米,您好,我正在搜索\ b元字符,它只将[ a-zA-Z0-9_]视为单词字符。因此对于包含减号char 的类名来说这是行不通的
斯塔诺

0

我认为完美的解决方案将是这样

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");

8
1.“使用普通JavaScript(不是jQuery)” 2.使用方括号
nkmol 2014年

3-使用括号
-TheBlackBenzKid

0

类'.bar'当前在哪个元素中?这是另一个解决方案,但这取决于您。

var reg = /Image/g, // regexp for an image element
query = document.querySelector('.bar'); // returns [object HTMLImageElement]
query += this.toString(); // turns object into a string

if (query.match(reg)) { // checks if it matches
  alert('the class .bar is attached to the following Element:\n' + query);
}

jsfiddle演示

当然,这仅是对1个简单元素<img>/Image/g)的查找,但是您可以将所有元素都放入<li>is /LI/g<ul>= /UL/getc之类的数组中。


0

只是为试图在嵌入式SVG元素中查找类名称的人们提供了答案。

将该hasCLass()功能更改为:

function hasClass(element, cls) {
    return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + cls + ' ') > -1;
  }

代替使用className属性,您需要使用getAttribute()方法来获取类名称。


0

我为我的网站创建了这些功能,我仅使用香草javascript,也许它将对某人有所帮助。首先,我创建了一个函数来获取任何HTML元素:

//return an HTML element by ID, class or tag name
    var getElement = function(selector) {
        var elements = [];
        if(selector[0] == '#') {
            elements.push(document.getElementById(selector.substring(1, selector.length)));
        } else if(selector[0] == '.') {
            elements = document.getElementsByClassName(selector.substring(1, selector.length));
        } else {
            elements = document.getElementsByTagName(selector);
        }
        return elements;
    }

然后是接收要删除的类的函数以及该元素的选择器:

var hasClass = function(selector, _class) {
        var elements = getElement(selector);
        var contains = false;
        for (let index = 0; index < elements.length; index++) {
            const curElement = elements[index];
            if(curElement.classList.contains(_class)) {
                contains = true;
                break;
            }
        }
        return contains;
    }

现在您可以像这样使用它:

hasClass('body', 'gray')
hasClass('#like', 'green')
hasClass('.button', 'active')

希望它会有所帮助。


0

提示:尽量删除项目中jQuery的依赖项-VanillaJS

document.firstElementChild返回<html>标签,然后classList属性返回添加到其中的所有类。

if(document.firstElementChild.classList.contains("your-class")){
    // <html> has 'your-class'
} else {
    // <html> doesn't have 'your-class'
}

-1

对我来说,最优雅,最快捷的方法是:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.