Test if an element contains a class?

2018-12-31 19:40发布

Using plain JavaScript (not jQuery), is there a way I can test to see if an element contains a class?

Currently, I'm doing this:

HTML:

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

JS:

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 = "";
}

This results in this output, which is correct:

I have class1

The issue is that if I change the HTML to this...

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

...there's no longer an exact match, so I get the default output of nothing (""). But I still want the output to be I have class1 because the <div> still contains the .class1 class.

23条回答
有味是清欢
2楼-- · 2018-12-31 20:20

A simplified oneliner:1

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

1 indexOf for arrays is not supported by IE (ofcourse). There are plenty of monkey patches to be found on the net for that.

查看更多
其实,你不懂
3楼-- · 2018-12-31 20:24

The easy and effective solution is trying .contains method.

test.classList.contains(testClass);
查看更多
心情的温度
4楼-- · 2018-12-31 20:24

This is supported on IE8+.

First we check if classList exists if it does we can use the contains method which is supported by IE10+. If we are on IE9 or 8 it falls back to using a regex, which is not as efficient but is a concise polyfill.

if (el.classList)
  el.classList.contains(className);
else
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
查看更多
与风俱净
5楼-- · 2018-12-31 20:24

Element.matches()

element.matches(selectorString)

According to MDN Web Docs:

The Element.matches() method returns true if the element would be selected by the specified selector string; otherwise, returns false.

Therefore, you can use Element.matches() to determine if an element contains a class.

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

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

View Browser Compatibility

查看更多
梦醉为红颜
6楼-- · 2018-12-31 20:29

Just to add to the answer for people trying to find class names within inline SVG elements.

Change the hasCLass() function to:

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

Instead of using the className property you'll need to use the getAttribute() method to grab the class name.

查看更多
路过你的时光
7楼-- · 2018-12-31 20:30

This is a little old, but maybe someone will find my solution helpfull:

// 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;
    }
}
查看更多
登录 后发表回答