如何用JavaScript判断dom是否有class的值?

<html class="no-js">
<head>
</head>
<body>
</body>
</html>

判断html节点的class是否有no-js

阅读 34.1k
12 个回答

说一下这个问题两个比较容易出错的点:

  • 字符串的indexOf方法是无法区分.no-js.no-js-indeed这样的类
  • 类名的分隔符可能不是空格,还有可能是\t等。

简单封装了一下,全浏览器兼容。所以ES5方法Array.prototype.indexOf在fallback里面就要绕过了。

var hasClass = (function(){
    var div = document.createElement("div") ;
    if( "classList" in div && typeof div.classList.contains === "function" ) {
        return function(elem, className){
            return elem.classList.contains(className) ;
        } ;
    } else {
        return function(elem, className){
            var classes = elem.className.split(/\s+/) ;
            for(var i= 0 ; i < classes.length ; i ++) {
                if( classes[i] === className ) {
                    return true ;
                }
            }
            return false ;
        } ;
    }
})() ;

alert( hasClass(document.documentElement, "no-js") ) ;
document.querySelector("html").classList.contains("no-js");
//or
document.querySelector("html").className.split(/\s+/g).indexOf("no-js") !== -1;

提供一个正则的答案

var hasClass = function(elem, className) {
    var reg = new RegExp('(^|\\s+)' + className + '($|\\s+)');
    return reg.test(elem.className);
};

测试:

var elem = document.getElementsByTagName('html')[0];
hasClass(elem, 'no-js'); // true

先说,如果你用 jQuery,那很简单

javascript$("html").hasClass("no-js")

如果你不用 jQuery,但是只考虑支持 HTML5 classList API 的浏览器,也很简单

javascriptdocument.querySelector("body").classList.contains("no-js")

如果还要兼容其它浏览器,那就不那么简单了,不妨看看 jQuery 的源码是怎么实现的 hasClass

javascriptvar rclass = /[\t\r\n\f]/g;

jQuery.fn.extend({
    hasClass: function(selector) {
        var className = " " + selector + " ",
            i = 0,
            l = this.length;
        for (; i < l; i++) {
            if (this[i].nodeType === 1 &&
                (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) > -1) {
                return true;
            }
        }

        return false;
    }
})

然后参照 jQuery 的代码,简化一下,自己实现个

javascriptfunction hasClass(dom, className) {
    className = className.replace(/^\s|\s$/g, "")

    return (
        " " + ((dom || {}).className || "").replace(/\s/g, " ") + " "
    ).indexOf(" " + className + " ") >= 0
}

当然,这个 hasClass 没考虑 className 参数包含多个 class 的情况,不过这种情况 classList API 也是直接抛的 Error,所以先不管了,将就用着吧。

window.onload = function () {
    var classStr = document.documentElement.getAttribute("class");
    var classArr = classStr.split(' ');
    if (classArr.indexOf('no-js')) {
        console.log('exists');
    }
}

以上确实错了,不会判断如no-js-abc的class。
更新如下:

window.onload = function () {
        var classStr = document.documentElement.getAttribute("class");
        var classArr = classStr.split(' ');
        console.log(classArr.some(function (element) { return element == 'no-js' }));
    }

修正了之前的bug,使用正则匹配

document.getElementsByTagName('html')[0].className.match(/(^|\s)no-js($|\s));
javascriptvar hasClass = function (targetClass, ele) {
    var reg = new RegExp('\\s' + targetClass);
    return reg.test(' ' + ele.className);
}

原理:ele.className获取到的字符串是用空格分开的多个class,例如'class1 class2 class3'
reg 构造的是要判断的类名并在前面加了个空白符,它能匹配' targetClass'这样的结构
最后用于test方法的是在前面加了空白的ele.className。
例子将变为reg.test(' class1 class2 class3')

javascriptdocument.getElementsByTagName('html')[0].className

拆分class,循环判断。

hasClass : function(ele,tagClass){
    if(!ele.className) return false;
    var aClass = ele.className.split(" "),
        bHas = false;
    for(var i=0,l = aClass.length;i<l;i++){
        if(aClass[i] === tagClass){
            bHas = true;
            break;
        }
    }
    return bHas;
}

简单,全端通用(DOM0),临时用一下的话:

/\bno-js\b/.test(document.getElementsByTagName('HTML')[0].className)

不过这个no-js主要是用于css里的

你可以用标签来判断

推荐问题
宣传栏