Що таке функція "hasClass" у простому JavaScript?


313

Як робити jQuery за hasClassдопомогою простого JavaScript? Наприклад,

<body class="foo thatClass bar">

Який спосіб JavaScript запитати, чи <body>є thatClass?


Я припускаю, що вам доведеться проаналізувати classвластивість (яка у випадку декількох класів матиме кілька імен класів у випадковому порядку, розділених пробілом) та перевірити, чи є в ній назва вашого класу. Не дуже складно, але все ж страшенно незручно, якщо не для навчальних цілей :)
Pekka,

7
не знаєш , якщо я спізнився на вечірку , але хороший сайт , який дає альтернативу функції JQuery є youmightnotneedjquery.com
Ітіль

Відповіді:


116

Ви можете перевірити, чи element.classNameвідповідають /\bthatClass\b/.
\bвідповідає слово перерва.

Або ви можете використовувати власну реалізацію jQuery:

var className = " " + selector + " ";
if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 

Щоб відповісти на більш загальне запитання, ви можете подивитися вихідний код jQuery на github або у джерелі, hasClassзокрема в цьому переглядачі джерела .


6
+1 за реалізацію jQuery (за те, що подивився (чи це правильна англійська мова?) Що rclassнасправді є;))
Фелікс Клінг,

6
Не \bвідповідає "thatClass-anotherClass"?
Меттью Крамлі

3
просто для повноти: rclass в останніх версіях є "/ [\ n \ t \ r] / g" (\ додано)
Фелікс Шварц

4
@FelixSchwarz правий, у поточному jQuery регексп оновлено до /[\t\r\n\f]/g. Також добре згадати, що це /\bclass\b/може бути невдаче для імен класів зі -знаком мінус (крім того, що це добре працює), тому реалізація jQuery є кращою та надійнішою. Наприклад: /\bbig\b/.test('big-text')повертає істину замість очікуваної помилки.
Стано

994

Просто використовуйте classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

Інші види використання classList:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

Підтримка браузера:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Опера 11.50
  • Сафарі 5.1

classList Підтримка браузера


5
Це не підтримується в IE8 . IE8 може отримати .classListрядок, але він не розпізнає більш сучасні методи, такі як.classList.contains()
iono

7
@iono У описі впровадження Element.classList від MDN є суть, яка розширює підтримку такої поведінки на розробник
Джеймс,

3
Я погоджуюся з @AlexanderWigmore, це було неймовірно корисно і просто.
Жак Олів'є

Голосує за це. Це набагато чистіший спосіб запиту класів
user2190488

@SLaks це слід оновити, щоб вже прийняти відповідь.
Умур Карагез

35

Найефективніший один лайнер, який

  • повертає булева (на відміну від відповіді Орблінга)
  • Не повертає хибний позитив при пошуку thisClassелемента, який має class="thisClass-suffix".
  • сумісний з будь-яким браузером до мінімум IE6

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

28

Атрибут, який зберігає використовувані класи, є className.

Тож ви можете сказати:

if (document.body.className.match(/\bmyclass\b/)) {
    ....
}

Якщо ви хочете розташування, яке показує, як jQuery робить все, я б запропонував:

http://code.jquery.com/jquery-1.5.js


1
Відмінно. matchАтрибут зручний знову! Чи справді jQuery робить щось більше, ніж можливо в JavaScript ?! Якщо ні, jQuery - це лише зайва вага скорочень.
animaacija

1
Це також відповідає myclass-something, як \bсірники сірники.
Марк Дурдін

1
@animaacija Усі бібліотеки / плагіни javascript в основному є скороченнями JavaScript, оскільки вони побудовані за допомогою JavaScript. Річ у цьому: скорочення завжди необхідні. Ніколи не винаходити колесо.
Едвін Стотелер

Це чудове рішення!
Мануель Абаскаль

28

// 1. Use if for see that classes:

if (document.querySelector(".section-name").classList.contains("section-filter")) {
  alert("Grid section");
  // code...
}
<!--2. Add a class in the .html:-->

<div class="section-name section-filter">...</div>


4
@greg_diesel: не відволікайте відповіді! Нові рішення загальних проблем є більш ніж вітаються.
raveren

2
@Raveren, хоча нові рішення старих проблем вітаються, ця конкретна відповідь не приносить нічого нового. Це лише додає шуму цьому питанню.
Еміль Бержерон

1
@raveren Це не нове рішення, це те саме, що ця відповідь, але з меншою кількістю інформації.
Фонд позову Моніки

13

функція hasClass:

HTMLElement.prototype.hasClass = function(cls) {
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] == cls) {
            return true;
        }
    }
    return false;
};

функція addClass:

HTMLElement.prototype.addClass = function(add) {
    if (!this.hasClass(add)){
        this.className = (this.className + " " + add).trim();
    }
};

функція RemoveClass:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName.trim();
};

11

Я використовую просте / мінімальне рішення, один рядок, крос-браузер, а також працює зі застарілими браузерами:

/\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'

Цей метод чудовий тим, що не потребує поліфілів, і якщо ви їх використовуєте, classListце набагато краще з точки зору продуктивності. Принаймні для мене.

Оновлення: я зробив крихітний поліфал, який я зараз використовую:

function hasClass(element,testClass){
  if ('classList' in element) { return element.classList.contains(testClass);
} else { return new Regexp(testClass).exec(element.className); } // this is better

//} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
  return false;
}

Для інших маніпуляцій класу дивіться повний файл тут .


2
Чи буде ця поїздка над класом notmyClassHere?
Teepeemm

2
Ви також можете запитати, чи немає вашого класу, і добре !/myClass/.test(document.body.className)помітите !символ.
thednp

1
Я не кажу про заперечення питання. Я думаю, що ваша функція буде неправильно повертати справжнє, якщо назва класу є thisIsmyClassHere.
Teepeemm

1
Я лише здогадувався, що це те, про що ви питаєте, не зрозумів, що саме вам потрібно, але ви спробували це, і не вдалося повернути справжнє / хибне як слід?
thednp

2
Це не є ідеальним, оскільки це не підтвердження рядків. Наприклад, коли document.body.className = 'myClass123', тоді /myClass/.test(document.body.className) повернути справжню ...
Zbigniew Wiadro

9

хорошим рішенням для цього є робота з classList і містить.

я зробив це так:

... for ( var i = 0; i < container.length; i++ ) {
        if ( container[i].classList.contains('half_width') ) { ...

Отже, вам потрібен ваш елемент і перевірте список класів. Якщо один із класів такий, як той, який ви шукаєте, він повернеться істинним, якщо ні, він поверне помилковим!


6

Використовуйте щось на кшталт:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');

3
Хіба це не еквівалент myHTMLSelector.classList.indexOf('the-class')? Ви теж не хочете >=0в кінці?
Teepeemm

5
Який сенс використовувати, [].indexOfякщо classListє containsметод?
Оріол

@Teepeemm ні. myHTMLSelector.classList.indexOf('the-class')повертає помилку, myHTMLSelector.classList.indexOf is not a functionтому що myHTMLSelector.classListце не масив. Але я здогадуюсь, коли це викликає за допомогою Array.prototypeдеякої конверсії. Це може підтримувати старіший браузер, хоча він containsмає дуже гарну підтримку.
Ehsan88


2

Ця функція "hasClass" працює в IE8 +, FireFox та Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}

1

Ну, всі вищезазначені відповіді є досить гарними, але ось невеличка проста функція, яку я прошив. Це працює досить добре.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}

3
У чому сенс ітерації, якщо classListє containsметод?
Оріол

1

Що ви думаєте про цей підхід?

<body class="thatClass anotherClass"> </body>

var bodyClasses = document.querySelector('body').className;
var myClass = new RegExp("thatClass");
var trueOrFalse = myClass.test( bodyClasses );

https://jsfiddle.net/5sv30bhe/


2
Я думаю, ви змішуєте свої імена змінних (active === myClass?). Але чи не дасть цей підхід помилковий позитив class="nothatClassIsnt"?
Teepeemm

0

Ось найпростіший спосіб:

var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
    if (allElements[i].hasAttribute("class")) {
         //console.log(allElements[i].className);
         if (allElements[i].className.includes("_the _class ")) { 
              console.log("I see the class");
         }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.