==
тесты для ссылочного равенства (независимо от того, являются ли они одним и тем же объектом).
.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 .
Используйте метод element.classList
.contains
:
element.classList.contains(class);
Это работает во всех текущих браузерах, а также есть полисы для поддержки старых браузеров.
Альтернативно, если вы работаете со старыми браузерами и не хотите использовать полисы для их исправления, использование indexOf
верное, но вы должны его настроить немного:
function hasClass(element, className) {
return (' ' + element.className + ' ').indexOf(' ' + className+ ' ') > -1;
}
В противном случае вы также получите true
, если класс, который вы ищете, является частью другого имени класса.
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;
}
}
Он также менее избыточен;)
Я думаю, что идеальным решением будет это
if ($(this).hasClass("your_Class"))
alert("positive");
else
alert("Negative");
Вот тривиальное решение без учета регистра:
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;
}
Это поддерживается на IE8 +.
Сначала мы проверяем, существует ли classList
, если это возможно, мы можем использовать метод contains
, который поддерживается IE10 +. Если мы находимся на IE9 или 8, он возвращается к использованию регулярного выражения, которое не так эффективно, но является кратким полифоном.
if (el.classList)
el.classList.contains(className);
else
new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
className
- это просто строка, поэтому вы можете использовать регулярную функцию indexOf , чтобы увидеть, содержит ли список классов другую строку.
foo
для элемента, который имеет класс foobar
.
– Zirak
5 May 2011 в 14:53
Это немного старо, но, возможно, кто-то найдет мое решение полезным:
// 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;
}
}
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; в вашем примере все случаи выполняли аналогичную операцию, но завтра вам может понадобиться делать разные вещи для каждого. Вы можете моделировать случай по умолчанию, указав переменную статуса, указывающую, было ли совпадение найдено в цикле или нет. Я бы Poly заполнил функциональность classList и использовал новый синтаксис. Таким образом, новый браузер будет использовать новую реализацию (которая намного быстрее), и только старые браузеры будут получать производительность от кода.
https://github.com/remy/polyfills/ BLOB / Master / classList.js
Попробуйте следующее:
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;
};
foo-bar
и поиск foo
.
– Felix Kling
5 May 2011 в 14:53
a-zA-Z0-9_
] как символы слова. Таким образом, для классных имен , содержащих минус char , это не сработает .
– Stano
11 June 2013 в 23:30
Упрощенный oneliner: 1
function hasClassName(classname,id) {
return String ( ( document.getElementById(id)||{} ) .className )
.split(/\s/)
.indexOf(classname) >= 0;
}
1 indexOf
для массивов не поддерживается IE (конечно). Для этого есть множество патчей для обезьян.
-
, рассматриваются как границы слов. Например. ищет foo
, а класс foo-bar
дает true
.
– Felix Kling
5 May 2011 в 15:57
Простое и эффективное решение пытается использовать метод .contains.
test.classList.contains(testClass);
Если элемент имеет только одно имя класса, вы можете быстро проверить его, получив атрибут класса. Другие ответы гораздо более надежны, но это, безусловно, имеет прецеденты.
if ( element.getAttribute('class') === 'classname' ) {
}
Для меня самый элегантный и быстрый способ добиться этого:
function hasClass(el,cl){
return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}
См. эту ссылку Codepen для быстрого и простого способа проверки элемента, если он имеет определенный класс с использованием ванильного JavaScript ~!
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
Я знаю много ответов, но большинство из них предназначены для дополнительных функций и дополнительных классов. Это я лично использую; намного чище и гораздо меньше строк кода!
if( document.body.className.match('category-page') ) {
console.log('yes');
}
<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);
}
Конечно, это всего лишь поиск одного простого элемента <img>
(/Image/g
), но вы можете поместить все в массив, например <li>
, /LI/g
, <ul>
= /UL/g
и т. д.
Поскольку он хочет использовать 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/>";
}
}
Я создал прототипный метод, который использует 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>
div
имеет два класса, но он будет выводитьI have class1
, когда вы используетеbreak
. Если вы хотите вывести каждый класс, который имеет элемент, вы можете просто взятьclassName
и разбить его на пробелы. Или какова ваша фактическая цель? – Felix Kling 5 May 2011 в 16:00