首页 文章

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

提问于
浏览
362

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

目前,我这样做:

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

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

I have class1

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

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

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

23 回答

  • 1

    试试这个:

    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;
    };
    
  • 0

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

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

    使用element.classList .contains 方法:

    element.classList.contains(class);
    

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


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

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

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

    DEMO

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


    Applied to the example:

    由于这与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;
        }
    }
    

    它也不那么多余;)

  • 8

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

    test.classList.contains(testClass);
    
  • 2

    在现代浏览器中,您只需使用Element.classListcontains 方法:

    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>
    

    支持的浏览器

    enter image description here

    (来自CanIUse.com


    Polyfill

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

  • 0

    既然他想使用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
    "; 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 += "(unknown class:" + testClasses[i] + ")
    "; } }
  • 33

    简化的oneliner:1

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

    IE(ofcourse)不支持1 indexOf for数组 . 网上有很多猴子补丁 .

  • -1

    这有点旧,但也许有人会发现我的解决方案有用:

    // 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;
        }
    }
    
  • 0

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

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

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

    OR


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

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

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

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

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

  • 0

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

    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;
    }
    
  • 1

    我知道有很多答案,但其中大部分都是针对其他功能和其他课程 . 这是我个人使用的那个;更清洁,更少的代码行!

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

    我创建了一个原型方法,如果可能的话,使用 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>
    

    测试页面

  • 3
    • Felix的添加空格的技巧是侧翼className和你正在搜索的字符串是确定元素是否具有类的正确方法 .

    • 要根据类具有不同的行为,您可以在 Map 中使用函数引用或函数:

    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语句中的代码一样;在您的示例中,所有案例都执行了类似的操作,但明天您可能需要为每个案例执行不同的操作 .

    • 您可以通过使用状态变量来判断是否在循环中找到匹配来模拟默认情况 .

  • 78

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

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

  • 0

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

    if ( element.getAttribute('class') === 'classname' ) {
    
    }
    
  • 5

    哪个元素当前是'.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 demo

    当然这只是一个简单的元素 <img>/Image/g )的查找,但你可以把所有数据放在像 <li> 这样的数组中 /LI/g<ul> = /UL/g 等 .

  • 5

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

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

  • 2

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

    hasClass (Vanilla JS)

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

    IE8支持此功能 .

    首先我们检查 classList 是否存在,如果可以,我们可以使用IE10支持的 contains 方法 . 如果我们使用的是IE9或8,它会回退到使用正则表达式,这不是那么有效但是是一个简洁的polyfill .

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

    只是为那些试图在内联SVG元素中找到类名的人添加答案 .

    hasCLass() 功能更改为:

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

    您不需要使用 className 属性,而是需要使用 getAttribute() 方法来获取类名 .

  • 5

    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

  • 0

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

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

相关问题