测试一个元素是否包含一个类?

daG*_*GUY 497 html javascript css dom

使用纯JavaScript(而不是jQuery),有没有一种方法可以测试一个元素是否包含一个类?

目前,我这样做:

HTML:

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 = "";
}
Run Code Online (Sandbox Code Playgroud)

JS:

<div id="test" class="class1"></div>
Run Code Online (Sandbox Code Playgroud)

这导致此输出,这是正确的:

<div id="test" class="class1 class5"></div>
Run Code Online (Sandbox Code Playgroud)

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

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 = "";
}
Run Code Online (Sandbox Code Playgroud)

...不再是完全匹配,所以我得到了默认输出("").但我还是想输出为I have class1,因为<div>包含.class1类.

Fel*_*ing 862

使用方法:element.classList .contains

element.classList.contains(class);
Run Code Online (Sandbox Code Playgroud)

这适用于所有当前浏览器,并且有polyfill也支持旧版浏览器.


或者,如果您使用旧版浏览器并且不想使用polyfill来修复它们,那么使用indexOf是正确的,但您必须稍微调整一下:

function hasClass(element, className) {
    return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}
Run Code Online (Sandbox Code Playgroud)

否则,true如果您要查找的班级是另一个班级名称的一部分,您也会得到.

DEMO

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它也不那么多余;)

  • @KayceBasques:因为我们还在 `cls` 中添加了空格,以便我们只匹配完整的类名。`hasClass(element, 'foo')` 不应与类 `foobar` 匹配。如果我们不向`element.className` 添加空格,我们将永远无法匹配第一个或最后一个类名。 (2认同)

dev*_*per 86

简单有效的解决方案是尝试.contains方法.

test.classList.contains(testClass);
Run Code Online (Sandbox Code Playgroud)

  • NB!并非所有浏览器都支持,更多信息请访问:http://caniuse.com/#feat=classlist (7认同)
  • `element.classList`属性的`contains`方法 (3认同)
  • 这是一个很好的答案,我相信.contains()现在有更广泛的支持. (3认同)

Joh*_*ers 42

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

testElement.classList.contains(className)
Run Code Online (Sandbox Code Playgroud)

演示

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')
});
Run Code Online (Sandbox Code Playgroud)
<div id="test" class="main main-content content"></div>
Run Code Online (Sandbox Code Playgroud)


支持的浏览器

在此输入图像描述

(来自CanIUse.com)


填充工具

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


Reg*_*Joe 20

这个问题得到了相当扎实的回答element.classList.contains(),但人们的答案相当夸张,并提出了一些大胆的主张,所以我运行了一个基准测试

请记住,每个测试都会进行 1000 次迭代,因此大多数测试仍然非常快。除非您在特定操作中广泛依赖于此,否则您不会看到性能差异。

我用基本上所有的方法进行了一些测试。在我的机器上(Win 10、24gb、i7-8700),classList.contains 表现得非常好。className.split(' ') 也是如此,实际上是相同的。

不过,获胜者是classList.contains(). 如果您不检查 classList 是否为undefined~(' ' + v.className + ' ').indexOf(' ' + classToFind + ' ')则会提前 5-15%

在此输入图像描述


Gra*_*ler 13

元素匹配()

element.matches(selectorString)

根据MDN 网络文档

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

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

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

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

查看浏览器兼容性


Tho*_*ght 9

既然他想使用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/>";
    }
}
Run Code Online (Sandbox Code Playgroud)


Kev*_*att 6

这里有一个小片段如果您正在尝试检查wether元素是否包含一个类,而不使用jQuery.

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

这说明元素可能包含由空格分隔的多个类名.

要么


您还可以将此功能分配给元素原型.

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

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

document.getElementById('MyDiv').hasClass('active');
Run Code Online (Sandbox Code Playgroud)


Dav*_*vid 5

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

  • 根据经验,这种方法可能非常危险:当您在具有 `foobar` 类的元素上查找类 `foo` 时,它会返回 true。 (7认同)
  • 当然,你只是知道你在测试什么。通过使用空格作为分隔符,Felix 的代码运行良好。 (2认同)

Koo*_*Inc 5

简化的oneliner:1

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

indexOfIE(ofcourse)不支持 1表示数组.网上有很多猴子补丁.


Dem*_*tic 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;
    }
}
Run Code Online (Sandbox Code Playgroud)


The*_*Kid 5

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

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}
Run Code Online (Sandbox Code Playgroud)