Получить имя класса HTML в Javascript [дубликат]

== тесты для ссылочного равенства (независимо от того, являются ли они одним и тем же объектом).

.equals() тесты для равенства значений (независимо от того, являются ли они логически «равными»).

Objects.equals () проверяет наличие null перед вызовом .equals(), поэтому вам не нужно (доступно с JDK7, также доступным в Guava ).

String.contentEquals () сравнивает содержимое String с содержимым любого CharSequence (доступно с Java 1.5).

Следовательно, если вы хотите проверить, имеет ли две строки одно и то же значение, вы, вероятно, захотите использовать Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Вы почти всегда хотите использовать Objects.equals(). В редкой ситуации, когда вы знаете, что имеете дело с интернированными строками, вы можете использовать ==.

Из JLS 3.10. 5. Строковые литералы :

Кроме того, строковый литерал всегда ссылается на тот же экземпляр класса String. Это связано с тем, что строковые литералы, или, в более общем смысле, строки, которые являются значениями константных выражений ( §15.28 ), «интернированы», чтобы обмениваться уникальными экземплярами, используя метод String.intern.

. Подобные примеры также можно найти в JLS 3.10.5-1 .

315
задан Thielicious 24 October 2017 в 12:18
поделиться

21 ответ

Используйте метод element.classList .contains:

element.classList.contains(class);

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


Альтернативно, если вы работаете со старыми браузерами и не хотите использовать полисы для их исправления, использование indexOf верное, но вы должны его настроить немного:

function hasClass(element, className) {
    return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}

В противном случае вы также получите true, если класс, который вы ищете, является частью другого имени класса.

DEMO

jQuery использует аналогичный (если не тот же) метод.


Применяется к примеру:

Поскольку это не работает вместе с коммутатором вы можете добиться такого же эффекта с помощью этого кода:

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;
    }
}

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

547
ответ дан rayphi 16 August 2018 в 00:02
поделиться
  • 1
    Удивительно, но как я могу использовать это в сочетании с оператором switch, чтобы я мог изменить вывод на основе того, какие классы содержит div? – daGUY 5 May 2011 в 15:53
  • 2
    @daGUY: Что вы хотите делать с оператором switch? Например. Второй div имеет два класса, но он будет выводить I have class1, когда вы используете break. Если вы хотите вывести каждый класс, который имеет элемент, вы можете просто взять className и разбить его на пробелы. Или какова ваша фактическая цель? – Felix Kling 5 May 2011 в 16:00
  • 3
    @Felix Kling: Мне нужно, чтобы innerHTML div изменялся между четырьмя различными строками в зависимости от того, какой класс он содержит. Я просто использовал & quot; у меня есть class1 & quot ;, и т. Д. В качестве примеров - реальные строки все разные. Я буду показывать только одну строку за раз, а не комбинировать (следовательно, разрывы после каждого случая). Я просто хочу, чтобы он по-прежнему работал, даже если соответствующий класс является одним из нескольких классов в div. – daGUY 5 May 2011 в 16:24
  • 4
    @daGUY: см. мое обновление ... – Felix Kling 5 May 2011 в 16:29
  • 5
    DEMO менее агрессивный jsfiddle.net/zBKCC/244 – nicolallias 31 March 2015 в 10:05

Я думаю, что идеальным решением будет это

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");
1
ответ дан Abhishek 16 August 2018 в 00:02
поделиться
  • 1
    1. «Использование простого JavaScript (не jQuery)» 2. Используйте скобки – nkmol 6 January 2014 в 11:21
  • 2
    3 - использование скобок – TheBlackBenzKid 7 August 2017 в 07:25

Вот тривиальное решение без учета регистра:

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;
}
2
ответ дан Anders Fjeldstad 16 August 2018 в 00:02
поделиться
0
ответ дан Arthur Tarasov 16 August 2018 в 00:02
поделиться

Это поддерживается на IE8 +.

Сначала мы проверяем, существует ли classList, если это возможно, мы можем использовать метод contains, который поддерживается IE10 +. Если мы находимся на IE9 или 8, он возвращается к использованию регулярного выражения, которое не так эффективно, но является кратким полифоном.

if (el.classList)
  el.classList.contains(className);
else
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
0
ответ дан Buts 16 August 2018 в 00:02
поделиться

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

3
ответ дан David 16 August 2018 в 00:02
поделиться
  • 1
    Как насчет тестирования класса class в приведенном выше примере? – Felix Kling 5 May 2011 в 14:47
  • 2
    Из опыта этот метод может быть весьма рискованным: он вернет true, если вы ищете класс foo для элемента, который имеет класс foobar. – Zirak 5 May 2011 в 14:53
  • 3
    @ Zirak: Это именно то, что я имел в виду ... – Felix Kling 5 May 2011 в 14:58
  • 4
    Конечно, вы просто знаете, что вы тестируете. Код Felix хорошо работает, используя пробелы в качестве разделителя. – David 5 May 2011 в 15:11
  • 5
    Не удается учесть вложенные экземпляры имени класса. Пример: «end» можно найти в имени класса «frontend». – Anthony Rutledge 4 June 2016 в 00:27

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

// 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
ответ дан Dementic 16 August 2018 в 00:02
поделиться
  • 1
    use: 'element.hasClass (' classname '); – Dementic 28 June 2012 в 13:12
  • 2
    Кстати, это будет работать в IE8 и выше. – Dementic 28 June 2012 в 13:24
  • 3
    Почему вы использовали t.length & gt; & gt; & gt; & gt; & gt; 0? Насколько я знаю, это noop, если вы используете «0», верно? – Vitor Canova 5 April 2013 в 17:53
  • 4
    вау столько кода для чего-то простого. Почему бы не использовать регулярное выражение, а не изобретать колесо? вы можете просто использовать /^class_name_you_are_searching_for$/.test(myElement.className) – pqsk 12 June 2013 в 22:31
  • 5
    Я написал это слишком быстро. Чтобы не перекомплементировать мое регулярное выражение, это будет /\s*class_name_you_are_searching_for\s*/.test(myElement.className) – pqsk 12 June 2013 в 23:10
0
ответ дан Dmitry 16 August 2018 в 00:02
поделиться
  1. Трюк Felix добавления полей для фланца классаName и строки, которую вы ищете, - это правильный подход к определению того, имеют ли элементы класс или нет.
  2. Чтобы иметь другое поведение в соответствии с к классу вы можете использовать ссылки или функции функций в пределах карты:
    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);
        }
    }
    
    для (var i in fns) выполняет итерацию через ключи в пределах карты fns. Без прерывания после того, как fnsi позволяет выполнять код всякий раз, когда есть совпадение, так что если у элемента есть, f.i., class1 и class2, будут выполняться как fn1, так и fn2. Преимущество этого подхода заключается в том, что код для выполнения для каждого класса является произвольным, как тот, который содержится в инструкции switch; в вашем примере все случаи выполняли аналогичную операцию, но завтра вам может понадобиться делать разные вещи для каждого. Вы можете моделировать случай по умолчанию, указав переменную статуса, указывающую, было ли совпадение найдено в цикле или нет.
1
ответ дан entonio 16 August 2018 в 00:02
поделиться

Я бы Poly заполнил функциональность classList и использовал новый синтаксис. Таким образом, новый браузер будет использовать новую реализацию (которая намного быстрее), и только старые браузеры будут получать производительность от кода.

https://github.com/remy/polyfills/ BLOB / Master / classList.js

1
ответ дан Eric Young 16 August 2018 в 00:02
поделиться

Попробуйте следующее:

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;
};
0
ответ дан jimy 16 August 2018 в 00:02
поделиться
30
ответ дан John Slegers 16 August 2018 в 00:02
поделиться

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

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

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

5
ответ дан KooiInc 16 August 2018 в 00:02
поделиться
  • 1
    Проблема с границами слов заключается в том, что некоторые допустимые символы для имен классов, такие как -, рассматриваются как границы слов. Например. ищет foo, а класс foo-bar дает true. – Felix Kling 5 May 2011 в 15:57
  • 2
    Ты прав. Убрали оригинал, добавили другой подход. Еще один лайнер. – KooiInc 5 May 2011 в 17:09

Простое и эффективное решение пытается использовать метод .contains.

test.classList.contains(testClass);
74
ответ дан Motti 16 August 2018 в 00:02
поделиться
  • 1
    contains метод свойства element.classList – user907860 2 June 2015 в 18:02
  • 2
    NB! Не поддерживается во всех браузерах, дополнительная информация здесь: caniuse.com/#feat=classlist – Silver Ringvee 29 March 2016 в 20:40
  • 3
    Это отличный ответ, и я верю, что .contains () имеет гораздо более широкую поддержку. – Nicholas Kreidberg 29 June 2017 в 13:59

Если элемент имеет только одно имя класса, вы можете быстро проверить его, получив атрибут класса. Другие ответы гораздо более надежны, но это, безусловно, имеет прецеденты.

if ( element.getAttribute('class') === 'classname' ) {

}
1
ответ дан Opal 16 August 2018 в 00:02
поделиться

Для меня самый элегантный и быстрый способ добиться этого:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}
-1
ответ дан Pinonirvana 16 August 2018 в 00:02
поделиться

См. эту ссылку Codepen для быстрого и простого способа проверки элемента, если он имеет определенный класс с использованием ванильного JavaScript ~!

hasClass (Vanilla JS)

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
4
ответ дан Simon 16 August 2018 в 00:02
поделиться
  • 1
    Я предпочитаю это решение больше. Это позволяет избежать вопроса о том, что имя класса частично соответствует другому классу и не требует, чтобы в IE выполнялись полисы. – scoota269 1 February 2017 в 23:45

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

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}
2
ответ дан TheBlackBenzKid 16 August 2018 в 00:02
поделиться
  • 1
    этот метод может возвращать ложные срабатывания при поиске имени класса, которое частично совпадает - например, <body class="category-page"> и document.body.className.match('page') - будет соответствовать, но нет класса page, прикрепленного к элементу – hooblei 7 March 2016 в 14:56

, в котором элемент в настоящее время является классом «.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

Конечно, это всего лишь поиск одного простого элемента <img> (/Image/g), но вы можете поместить все в массив, например <li>, /LI/g, <ul> = /UL/g и т. д.

0
ответ дан Thielicious 16 August 2018 в 00:02
поделиться

Поскольку он хочет использовать 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/>";
    }
}
8
ответ дан Thought 16 August 2018 в 00:02
поделиться
  • 1
    Мне просто интересно было то же самое, но да, это самое близкое к оригинальной проблеме! – Silver Ringvee 29 March 2016 в 20:44

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

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

2
ответ дан vsync 16 August 2018 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: