Проверить, содержит ли элемент класс?
используя простой JavaScript (не jQuery), есть ли способ проверить, есть ли элемент содержит класс?
в настоящее время я делаю это:
HTML-код:
<div id="test" class="class1"></div>;
JS:
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 = "";
}
это приводит к этому выходу, который является правильным:
I have class1
проблема в том, что если я изменю HTML на это...
<div id="test" class="class1 class5"></div>
...там больше нет точного соответствия, поэтому я получаю вывод по умолчанию ничего (""
). Но я все равно хочу, чтобы выход был I have class1
, потому что <div>
еще содержит на .class1
класса.
22 ответов
использовать element.classList
.contains
способ:
element.classList.contains(class);
это работает на всех текущих браузерах, и есть polyfills для поддержки старых браузеров тоже.
как вариант, если вы работаете со старыми браузерами и не хотите использовать polyfills для их исправления, используя indexOf
правильно, но вы должны настроить его немного:
function hasClass(element, className) {
return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}
в противном случае вы также получите true
если класс, который вы ищете является частью другого названия класса.
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;
}
}
это также менее лишними ;)
в современных браузерах, вы можете просто использовать 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>
поддерживаемые браузеры
(от CanIUse.com)
Polyfill
если вы хотите использовать Element.classList
но вы также хотите поддерживать старые браузеры, рассмотрите возможность использования это polyfill by Эли-Серый.
поскольку он хочет использовать 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/>";
}
}
упрощенный oneliner:1
function hasClassName(classname,id) {
return String ( ( document.getElementById(id)||{} ) .className )
.split(/\s/)
.indexOf(classname) >= 0;
}
1indexOf
для массивов не поддерживается IE (конечно). Есть много патчи можно найти в сети для этого.
Это немного старо, но, возможно, кто-то найдет мое решение полезным:
// 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;
}
}
вот небольшой фрагмент, Если вы пытаетесь проверить, содержит ли элемент wether класс, без использования 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 ):
document.getElementById('MyDiv').hasClass('active');
className
- Это просто строка, поэтому вы можете использовать обычный indexOf функция, чтобы увидеть, содержит ли список классов другую строку.
вот тривиальное решение без учета регистра:
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;
}
Я знаю там много ответов, но большинство из них предназначены для дополнительных функций и дополнительных занятий. Это тот, который я лично использую; намного чище и намного меньше строк кода!
if( document.body.className.match('category-page') ) {
console.log('yes');
}
Я создал метод прототипа, который использует 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>
тестовая страница
трюк Феликса добавления пробелов для фланга 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 i в fns) перебирает ключи внутри карты fns.
- не иметь никакой перерыв после фнси позволяет код должен выполняться всякий раз, когда есть совпадение - так что если элемент имеет, f.Я., class1 и class2, оба fn1 и fn2 будут выполнены.
- преимущество этого подхода заключается в том, что код для выполнения для каждого класса является произвольным, как и в инструкции switch; в вашем примере все случаи выполняли аналогичную операцию, но завтра вам может потребоваться сделать разные вещи для каждого.
- вы можете имитировать случай по умолчанию, имея переменную состояния, сообщающую, является ли совпадение было найдено в петле или нет.
Я думаю, что идеальным решением будет это
if ($(this).hasClass("your_Class"))
alert("positive");
else
alert("Negative");
Я бы Поли заполнить функциональность classList и использовать новый синтаксис. Таким образом, новый браузер будет использовать новую реализацию (что намного быстрее), и только старые браузеры будут получать хит производительности из кода.
если элемент имеет только одно имя класса, вы можете быстро проверить его, получив атрибут class. Другие ответы гораздо более надежны, но это, безусловно, имеет свои варианты использования.
if ( element.getAttribute('class') === 'classname' ) {
}
попробуй это:
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;
};
в каком элементе в настоящее время находится класс'.бар ? Вот еще одно решение, но это зависит от вас.
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);
}
конечно, это только поиск для 1 простого элемента <img>
(/Image/g
), но вы можете поместить все в массив, как <li>
is /LI/g
, <ul>
= /UL/g
etc.
Это немного выключено, но если у вас есть событие, которое запускает переключатель, вы можете обойтись без классов:
<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
.
Это немного hacky, но работает долго переключается без дополнительных функций или циклов
см. эту ссылку Codepen для более быстрого и простого способа проверки элемента, если он имеет определенный класс с помощью vanilla JavaScript~!
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
это поддерживается на IE8+.
Сначала мы проверяем, если если это так, мы можем использовать contains
метод, который поддерживается IE10+. Если мы на IE9 или 8 он использует регулярное выражение, которое является не как эффективным, но является кратким полифилл.
if (el.classList)
el.classList.contains(className);
else
new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
просто добавить к ответу для людей, пытающихся найти имена классов внутри встроенных элементов SVG.
изменить
для меня самый элегантный и быстрый способ достижения это:
function hasClass(el,cl){
return !!el.className && !!el.className.match(new RegExp('\b('+cl+')\b'));
}