Что такое функция hasClass с простым JavaScript?

313

Как вы делаете JQuery hasClassс простым старым JavaScript? Например,

<body class="foo thatClass bar">

Какой способ спросить JavaScript, если <body>есть thatClass?

рукав моря
источник
Я предполагаю, что вам придется проанализировать classсвойство (которое в случае нескольких классов будет иметь несколько имен классов в случайном порядке, разделенных пробелом) и проверить, есть ли в нем имя вашего класса. Не очень сложно, но все равно ужасно неудобно, если не в учебных целях :)
Pekka
7
не знаю, опаздываю ли я на вечеринку, но хороший сайт, который дает альтернативы функциям jQuery, это youmightnotneedjquery.com
ithil

Ответы:

116

Вы можете проверить, element.classNameсоответствует ли /\bthatClass\b/.
\bсоответствует разрыву слова.

Или вы можете использовать собственную реализацию jQuery:

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

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

SLaks
источник
6
+1 за реализацию jQuery (за то, что посмотрел (это правильный английский?), Что на rclassсамом деле;))
Феликс Клинг
6
Не будет \bсоответствовать "thatClass-anotherClass"?
Мэтью Крамли
3
просто для полноты: rclass в последних версиях "/ [\ n \ t \ r] / g" (\ r добавлено)
Феликс Шварц
4
@FelixSchwarz прав, в текущем jQuery регулярное выражение было обновлено до /[\t\r\n\f]/g. Также стоит упомянуть, что /\bclass\b/может произойти сбой для имен классов со -знаком минус (кроме того, что он работает хорошо), поэтому реализация jQuery лучше и надежнее. Например: /\bbig\b/.test('big-text')возвращает true вместо ожидаемого false.
Стано
996

Просто используйте 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
  • Safari 5.1

classList Поддержка браузера

Damien
источник
5
Это не поддерживается в IE8 . IE8 может быть извлечен .classListкак строка, но он не распознает более современные методы, такие как.classList.contains()
iono
7
@iono В описании реализации Element.classList из MDN есть прокладка, которая расширяет поддержку этого поведения до IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
Джеймс
3
Я согласен с @AlexanderWigmore, это было невероятно полезно и просто.
Жак Оливье
Голосует за это. Это гораздо более чистый способ запроса классов
user2190488
@SLaks это должно быть обновлено, чтобы быть уже принятым ответом.
Умур Карагез
35

Самый эффективный лайнер, который

  • возвращает логическое значение (в отличие от ответа Орблинга)
  • Не возвращает ложное срабатывание при поиске thisClassэлемента, который имеет class="thisClass-suffix".
  • совместим с любым браузером вплоть до IE6

function hasClass( target, className ) {
    return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
}
raveren
источник
28

Атрибут , который хранит классы в использовании является className.

Итак, вы можете сказать:

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

Если вы хотите местоположение, которое показывает вам, как jQuery делает все, я бы предложил:

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

Orbling
источник
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>

StiveAZ
источник
4
@greg_diesel: не препятствуйте ответам! Новые решения для общих проблем приветствуются.
Раверен
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;
}

Для других манипуляций с классами, смотрите полный файл здесь .

thednp
источник
2
Будет ли это путешествие над классом notmyClassHere?
Teepeemm
2
Вы также можете спросить, если вашего класса нет, также !/myClass/.test(document.body.className)обратите внимание на !символ.
Thednp
1
Я не говорю об отрицании вопроса. Я думаю, что ваша функция неправильно вернет true, если имя класса thisIsmyClassHere.
Teepeemm
1
Я только догадывался, что это то, о чем ты спрашиваешь, не понял точно, что тебе нужно, но пробовал ли ты, и он не смог вернуть истину / ложь, как и должно быть?
thednp
2
Это не идеально, так как это не доказательство подстрок. Например, когда document.body.className = 'myClass123', тогда /myClass/.test(document.body.className) возвращают true ...
Zbigniew Wiadro
9

Хорошим решением для этого является работа с classList и содержит.

я сделал это так:

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

Итак, вам нужен ваш элемент и проверьте список классов. Если один из классов совпадает с тем, который вы ищете, он вернет true, если нет - false!

Бастиан Фиссингер
источник
6

Используйте что-то вроде:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Алехандро Нанез
источник
3
Разве это не эквивалентно myHTMLSelector.classList.indexOf('the-class')? Разве вы не хотите >=0в конце?
Teepeemm
5
Какой смысл использовать [].indexOfесли classListесть containsметод?
Ориоль
@ Типимм нет. myHTMLSelector.classList.indexOf('the-class')возвращает ошибку, myHTMLSelector.classList.indexOf is not a functionпотому что myHTMLSelector.classListэто не массив. Но я думаю, что при вызове с использованием Array.prototypeкакого-либо преобразования происходит. Это может поддерживать старый браузер, но containsимеет очень хорошую поддержку.
Ehsan88
4
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
Александр Карбивничий
источник
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);
}
manufosela
источник
1

Ну, все вышеприведенные ответы довольно хороши, но вот небольшая простая функция, которую я выбрал. Это работает довольно хорошо.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}
j0hnstew
источник
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/

Marian07
источник
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");
         }
    }
}
Сообщество Ans
источник