Проверить, содержит ли элемент класс в JavaScript? - PullRequest
446 голосов
/ 05 мая 2011

Используя простой 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 класс.

Ответы [ 23 ]

763 голосов
/ 05 мая 2011

Использование element.classList .contains метод:

element.classList.contains(class);

Это работает во всех текущих браузерах, и есть полифилы для поддержки старых браузеров.


В качестве альтернативы , если вы работаете с более старыми браузерами и не хотите использовать полифиллы для их исправления, используйте 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;
    }
}

Это также менее избыточно;)

84 голосов
/ 28 мая 2015

Простое и эффективное решение - метод .contains .

test.classList.contains(testClass);
40 голосов
/ 20 января 2016

В современных браузерах вы можете просто использовать contains метод Element.classList:

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, но также хотите поддерживать более старые браузеры, рассмотрите возможность использования этого полифилла by Эли Грей .

9 голосов
/ 18 мая 2012

Так как он хочет использовать 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/>";
    }
}
6 голосов
/ 28 мая 2015

Вот небольшой фрагмент кода. Если вы пытаетесь проверить, не содержит ли элемент элемента класс, без использования 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 голосов
/ 28 июня 2012

Это немного старо, но, возможно, кто-то найдет мое решение полезным:

// 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;
    }
}
5 голосов
/ 05 мая 2011

Упрощенный oneliner: 1

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

1 indexOf для массивов не поддерживаетсяIE (конечно).Для этого в сети можно найти множество обезьяньих заплат.

4 голосов
/ 21 декабря 2015

Я знаю там много ответов, но большинство из них для дополнительных функций и дополнительных классов.Это тот, который я лично использую;намного чище и намного меньше строк кода!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}
3 голосов
/ 05 мая 2011

className - это просто строка, поэтому вы можете использовать обычную функцию indexOf , чтобы увидеть, содержит ли список классов другую строку.

2 голосов
/ 14 октября 2014

Я создал метод-прототип, который использует 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>

Тестовая страница

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...