Проверить, содержит ли элемент класс в JavaScript?
Используя простой 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>
Ответы
Ответ 1
Используйте 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;
}
}
Это также менее избыточно;)
Ответ 2
Простое и эффективное решение пытается использовать .contains.
test.classList.contains(testClass);
Ответ 3
В современных браузерах вы можете просто использовать метод contains
Element.classList
:
testElement.classList.contains(className)
Demo
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>
Ответ 4
Поскольку он хочет использовать 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/>";
}
}
Ответ 5
Вот небольшой фрагмент кода. Если вы пытаетесь проверить, содержит ли элемент класс, без использования 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);
};
И запустить его так (очень похоже на функцию .hasClass()
):
document.getElementById('MyDiv').hasClass('active');
Ответ 6
Упрощенный oneliner: 1
function hasClassName(classname,id) {
return String ( ( document.getElementById(id)||{} ) .className )
.split(/\s/)
.indexOf(classname) >= 0;
}
1indexOf
для массивов не поддерживается IE (конечно). Для этого есть множество патчей для обезьян.
Ответ 7
Это немного старо, но, возможно, кто-то найдет мое решение полезным:
// Fix IE 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;
}
}
Ответ 8
className
- это просто строка, поэтому вы можете использовать регулярную функцию indexOf, чтобы узнать, содержит ли список классов другую строку.
Ответ 9
Я знаю много ответов, но большинство из них предназначены для дополнительных функций и дополнительных классов. Это я лично использую; гораздо чище и гораздо меньше строк кода!
if( document.body.className.match('category-page') ) {
console.log('yes');
}
Ответ 10
Здесь не зависящее от регистра тривиальное решение:
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;
}
Ответ 11
Я создал прототип метода, который использует 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 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>
Ответ 12
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>
Ответ 13
-
Уловка Felix с добавлением пробелов для флажков className и искомая строка - это правильный подход к определению того, имеют ли элементы класс или нет.
-
Чтобы иметь другое поведение в соответствии с классом, вы можете использовать ссылки на функции или функции в пределах карты:
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; в вашем примере все случаи выполняли аналогичную операцию, но завтра вам может понадобиться делать разные вещи для каждого.
- Вы можете моделировать случай по умолчанию, указав переменную статуса, указывающую, было ли совпадение найдено в цикле или нет.
Ответ 14
Я бы Poly заполнил функциональность classList и использовал новый синтаксис. Таким образом, новый браузер будет использовать новую реализацию (которая намного быстрее), и только старые браузеры будут получать производительность от кода.
https://github.com/remy/polyfills/blob/master/classList.js
Ответ 15
Если элемент имеет только одно имя класса, вы можете быстро его проверить, получив атрибут class. Другие ответы гораздо более надежны, но это, безусловно, имеет прецеденты.
if ( element.getAttribute('class') === 'classname' ) {
}
Ответ 16
Попробуйте следующее:
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;
};
Ответ 17
Я думаю, что идеальным решением будет этот
if ($(this).hasClass("your_Class"))
alert("positive");
else
alert("Negative");
Ответ 18
в котором в данный момент находится класс '.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
Конечно, это только поиск 1 простого элемента <img>
(/Image/g
), но вы можете поместить все в массив, например <li>
is /LI/g
, <ul>
= /UL/g
и т.д.
Ответ 19
Это немного не работает, но если у вас есть событие, запускающее переключатель, вы можете обойтись без классов:
<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
.
Немного взломан, но работает для длинных переключателей без дополнительных функций или циклов.
Ответ 20
Посмотрите эту ссылку Codepen для более быстрого и простого способа проверки элемента, если у него есть определенный класс, использующий ванильный JavaScript ~!
hasClass (Vanilla JS)
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
Ответ 21
Это поддерживается на IE8+.
Сначала мы проверяем, существует ли classList
если он есть, мы можем использовать метод contains
который поддерживается IE10+. Если мы находимся на IE9 или 8, то возвращаемся к использованию регулярного выражения, которое не так эффективно, но является кратким полифилом.
if (el.classList)
el.classList.contains(className);
else
new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
Ответ 22
Просто чтобы добавить к ответу людей, пытающихся найти имена классов внутри встроенных элементов SVG.
Измените hasCLass()
на:
function hasClass(element, cls) {
return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + cls + ' ') > -1;
}
Вместо использования свойства className
вам нужно использовать метод getAttribute()
чтобы получить имя класса.
Ответ 23
Для меня самый элегантный и быстрый способ добиться этого:
function hasClass(el,cl){
return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}