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

时间:2011-05-05 13:40:20

标签: javascript html css dom

使用纯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>

...不再是精确匹配,所以我得到的是默认输出("")。但我仍然希望输出为I have class1,因为<div>仍然包含 .class1类。

29 个答案:

答案 0 :(得分:736)

使用element.classList .contains方法:

element.classList.contains(class);

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


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

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

否则,如果您要查找的班级是另一个班级名称的一部分,您也会获得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;
    }
}

它也不那么多余;)

答案 1 :(得分:83)

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

test.classList.contains(testClass);

答案 2 :(得分:39)

在现代浏览器中,您只需使用Element.classListFB Object is not defined方法:

contains

演示

&#13;
&#13;
testElement.classList.contains(className)
&#13;
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')
});
&#13;
&#13;
&#13;

支持的浏览器

enter image description here

(来自CanIUse.com

填充工具

如果您想使用Element.classList但又想支持旧版浏览器,请考虑this polyfill使用Eli Grey

答案 3 :(得分: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/>";
    }
}

答案 4 :(得分:6)

这是一个小片段如果您正在尝试检查wether元素是否包含一个类,而不使用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');

答案 5 :(得分:5)

简化的oneliner: 1

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

1 indexOf数组。网上有很多猴子补丁。

答案 6 :(得分: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;
    }
}

答案 7 :(得分:3)

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

答案 8 :(得分: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;
}

答案 9 :(得分:2)

我已经创建了一个使用classList的原型方法,如果可能的话,还会转到indexOf

&#13;
&#13;
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') );
&#13;
<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>
&#13;
&#13;
&#13;

Test page

答案 10 :(得分:2)

要检查元素是否包含类,请使用元素的 classList 属性的 contains() 方法:*

element.classList.contains(className);

*假设您有以下元素:

<div class="secondary info">Item</div>*

要检查元素是否包含二级类,请使用以下代码:

 const div = document.querySelector('div');
 div.classList.contains('secondary'); // true

以下返回 false,因为元素没有类错误:

 const div = document.querySelector('div');
 div.classList.contains('error'); // false

答案 11 :(得分:2)

Element.matches()

element.matches(selectorString)

根据MDN Web Docs

  

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

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

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

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

View Browser Compatibility

答案 12 :(得分: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 fns)遍历fns映射中的键。
    • 在fnsi之后没有中断允许代码在匹配时执行 - 所以如果元素有,f.i。,class1和class2,则将执行fn1和fn2。
    • 这种方法的优点是每个类执行的代码是任意的,就像switch语句中的代码一样;在您的示例中,所有案例都执行了类似的操作,但明天您可能需要为每个案例执行不同的操作。
    • 您可以通过使用状态变量来判断是否在循环中找到匹配项来模拟默认情况。

答案 13 :(得分:1)

我会Poly填充classList功能并使用新语法。这种方式较新的浏览器将使用新的实现(速度更快),只有旧的浏览器才能从代码中获得性能。

https://github.com/remy/polyfills/blob/master/classList.js

答案 14 :(得分:1)

如果元素只有一个类名,您可以通过获取class属性快速检查它。其他答案要强得多,但这肯定有它的用例。

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

}

答案 15 :(得分:1)

正如接受的答案所暗示的那样,Element.className 返回一个字符串,因此您可以使用 indexOf() 方法轻松检查类是否存在:

element.className.indexOf('animated') > -1

如果您对 indexOfclassList.contains 之间的性能差异感兴趣,使用 indexOf 似乎稍快一些。我做了一个快速的基准性能测试来检查。以下是我的发现:ClassName.indexOf vs ClassList.contains

答案 16 :(得分:1)

使用classList也很理想

HTML

<div id="box" class="myClass"></div>

JavaScript

const element = document.querySelector("#box");

element.classList.contains("myClass");

答案 17 :(得分:0)

element.classList.contains() 非常肯定地回答了这个问题,但人们的回答非常夸张,并提出了一些大胆的主张,so I ran a benchmark

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

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

赢家是classList.contains()。如果您不检查 classList 是否为 undefined,则 ~(' ' + v.className + ' ').indexOf(' c' + i + ' ') 会提前 5-15%

enter image description here

答案 18 :(得分:0)

由于.className是字符串,因此可以使用字符串includes()方法来检查您的element.className.includes("class1") 是否包含您的类名:

{{1}}

答案 19 :(得分: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'
}

答案 20 :(得分: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')

希望这会有所帮助。

答案 21 :(得分:0)

对于试图在嵌入式SVG元素中查找类名称的人们来说,这只是一个补充。

hasCLass()函数更改为:

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

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

答案 22 :(得分:0)

IE8 +支持此功能。

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

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

答案 23 :(得分:0)

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

http://www.mastertheboss.com/javaee/batch-api/running-batch-jobs-in-j2se-applications

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

答案 24 :(得分:0)

这有点偏,但如果你有一个触发开关的事件,你可以不用上课:

<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,但适用于没有额外功能或循环的长开关

答案 25 :(得分:0)

哪个元素目前是班级&#39; .bar&#39; ?这是另一种解决方案,但它取决于你。

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 demo

当然,这只是对1个简单元素<img>/Image/g)的查找,但您可以将所有数据放入<li> /LI/g <ul>,{{1} }} = /UL/g等。

答案 26 :(得分: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;
};

答案 27 :(得分:0)

我认为完美的解决方案就是这个

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

答案 28 :(得分:-1)

对我而言,实现它的最优雅,更快捷的方法是:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}