Bir öğenin JavaScript'te sınıf içerip içermediğini kontrol ettiniz mi?


588

Düz JavaScript (jQuery değil) kullanma, Bir öğenin sınıf içerip içermediğini kontrol etmenin herhangi bir yolu var mı ?

Şu anda bunu yapıyorum:

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>

Sorun şu ki, HTML'yi bu şekilde değiştirirsem ...

<div id="test" class="class1 class5"></div>

... artık tam bir eşleşme yok, bu yüzden hiçbir şeyin varsayılan çıktısını alıyorum ( ""). Ama yine de çıkış olmak istiyorum I have class1çünkü <div>hala içeren.class1 sınıf.


5
element.classList.contains (cls)
Ronnie Royston

Yanıtlar:


1038

Yöntemi kullanın :element.classList .contains

element.classList.contains(class);

Bu, mevcut tüm tarayıcılarda çalışır ve eski tarayıcıları da destekleyen çoklu dolgular vardır.


Alternatif olarak , eski tarayıcılarla çalışıyorsanız ve bunları düzeltmek için çoklu dolgular kullanmak istemiyorsanız, kullanım indexOfdoğrudur, ancak biraz ince ayar yapmanız gerekir:

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

Aksi takdirde true, aradığınız sınıf başka bir sınıf adının parçasıysa da elde edersiniz .

DEMO

jQuery benzer (aynı değilse) bir yöntem kullanır.


Örneğe uygulanır:

Bu, switch ifadesiyle birlikte çalışmadığından, bu kodla aynı etkiyi elde edebilirsiniz:

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

Ayrıca daha az yedeklidir;)


Harika, ama div ifadesini içeren sınıflara göre çıktıyı değiştirebilmem için bunu switch deyimi ile birlikte nasıl kullanabilirim?
DaGUY

@daGUY: Switch deyimiyle ne yapmak istiyorsun? Örneğin, ikincisi diviki sınıfa sahiptir, ancak yalnızca I have class1kullandığınız gibi çıkacaktır break. Bir öğenin sahip olduğu her sınıfı çıkarmak istiyorsanız, classNameonu beyaz boşluklara alıp bölebilirsiniz. Veya asıl amacınız nedir?
Felix Kling

@Felix Kling: İçerdiği sınıfa bağlı olarak dört farklı dize arasında geçiş yapmak için div'in innerHTML'sine ihtiyacım var. Ben sadece örnek olarak "I class1 var", vb kullandım - gerçek dizeleri hepsi farklı. Ben sadece (her durumda sonra tatili) birleştirerek değil, bir seferde sadece bir dize gösterilecektir. Ben sadece eşleşen sınıf div birden çok sınıftan biri olsa bile hala çalışmasını istiyorum.
DaGUY

@ Felix Kling: bunu yaptı, çok teşekkürler! Aslında sınıfların adlarını değil, tamamen farklı dizelerden birini çıktı değilim, bu yüzden her birini işlemek için birkaç IF / ELSE IF deyimleri ile biraz değiştirdim. Yine de mükemmel çalışıyor.
DaGUY

1
Öncesi ve sonrası boşluk eklemenizin özel bir nedeni var mı?
Ced


49

Modern tarayıcılarda, sadece şu containsyöntemi kullanabilirsiniz Element.classList:

testElement.classList.contains(className)

gösteri

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>


Desteklenen tarayıcılar

resim açıklamasını buraya girin

( CanIUse.com'dan )


polyfill

Kullanmak isterseniz Element.classListama aynı zamanda eski tarayıcıları desteklemek istiyoruz, kullanmayı düşünün bu polyfill tarafından Eli Gray .


10

Switch () kullanmak istediğinden, henüz kimse bunu ortaya koymadı:

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

1
Sadece aynı şeyi merak ediyordum, ama evet, bu orijinal soruna en yakın olanı!
Silver Ringvee

8

Element.matches ()

element.matches (selectorString)

Göre MDN Web Dokümanlar :

Element.matches()Yöntem döner trueöğesi belirtilen seçici dize seçilebilir eğer; aksi takdirde geri döner false.

Bu nedenle, Element.matches()bir öğenin sınıf içerip içermediğini belirlemek için kullanabilirsiniz .

const element = document.querySelector('#example');

console.log(element.matches('.foo')); // true
<div id="example" class="foo bar"></div>

Tarayıcı Uyumluluğunu Görüntüle


7

İşte küçük bir snippet: Eğer jQuery kullanmadan, bir öğe içerip içermediğini kontrol etmeye çalışıyorsanız.

function hasClass(element, className) {
    return element.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className);
}

Bu, öğenin boşlukla ayrılmış birden fazla sınıf adı içerebileceğini açıklar.

VEYA


Bu işlevi ayrıca eleman prototipine de atayabilirsiniz.

Element.prototype.hasClass = function(className) {
    return this.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(this.className);
};

Ve bu şekilde tetikleyin (jQuery .hasClass()işlevine çok benzer ):

document.getElementById('MyDiv').hasClass('active');

Bu çözümü daha çok tercih ediyorum. Sınıf adının başka bir sınıfla kısmen eşleşmesi sorununu önler ve IE'de çalışmak için çoklu dolgu gerektirmez.
scoota269

5

Basitleştirilmiş bir oneliner: 1

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

indexOfDiziler için 1 , IE (tabii ki) tarafından desteklenmemektedir. Bunun için internette bol miktarda maymun yaması var.


1
Sözcük sınırları ile ilgili sorun, sınıf adları için bazı geçerli karakterlerin -sözcük sınırı olarak kabul edilmesidir. Örneğin aramak foove sınıf foo-barverimdir true.
Felix Kling

Haklısın. Orijinal kaldırıldı, başka bir yaklaşım ekledi. Hala bir oneliner.
KooiInc

5

Bu biraz eski, ama belki birisi benim çözümümü yararlı bulabilir:

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

use: 'element.hasClass (' sınıf adı ');
Dementic

Neden t.length >>> 0 kullandınız? Bildiğim kadarıyla '0' kullanırsanız bir noop, değil mi?
Vitor Canova

vay basit bir şey için çok fazla kod. Neden düzenli bir ifade kullanmıyor ve tekerleği yeniden icat etmiyorsunuz? /^class_name_you_are_searching_for$/.test(myElement.className) kullanabilirsiniz
pqsk

1
Bunu çok hızlı yazdım. Normal ifademi fazla karmaşıklaştırmamak için /\s*class_name_you_are_searching_for\s*/.test(myElement.className)
pqsk

@pqsk - Gelecekte kullanmak üzere kendi kütüphanelerimi yazıyorum. ve bu sadece yığınıma ekliyor. Tabii ki diğer çözümler işe yarayacaktı, bu sadece benim tercih
ettiğim

4

classNamesınıfın başka bir dize içerip içermediğini görmek için normal indexOf işlevini kullanabilirsiniz.


1
classYukarıdaki örnekte sınıf testi yapmaya ne dersiniz ?
Felix Kling

6
Deneyimden, bu yöntem oldukça riskli olabilir: Sınıfı fooolan bir öğede sınıfı aradığınızda doğru dönecektir foobar.
Zirak

2
Elbette, sadece ne test ettiğinin farkındasın. Felix'in kodu boşlukları sınırlayıcı olarak kullanarak iyi çalışır.
David

Sınıf adının iç içe geçmiş örneklerini dikkate almaz. Örnek: 'end', 'frontend' sınıf adında bulunabilir.
Anthony Rutledge

4

Ben çok cevap var biliyorum ama bunların çoğu ek fonksiyonlar ve ek sınıflar içindir. Şahsen kullandığım bu; çok daha temiz ve çok daha az kod satırı!

if( document.body.className.match('category-page') ) { 
  console.log('yes');
}

1
bu yöntem, kısmen eşleşen - örneğin <body class="category-page">ve document.body.className.match('page')- eşleşecek ancak pageöğeye bağlı bir sınıf yok
hooblei 7:16

İle çözülebilir \börneğin /\bpage\b/g(Kullanım zorunda not 's regex beri / /g).
Andrew

2

İşte büyük / küçük harfe duyarlı olmayan önemsiz bir çözüm:

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

Öğenin yalnızca bir sınıf adı varsa, sınıf özniteliğini alarak bunu hızlı bir şekilde kontrol edebilirsiniz. Diğer cevaplar çok daha sağlamdır, ancak bunun kesinlikle kullanım durumları vardır.

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

}

2

classListMümkünse başka tatil köyleri kullanan bir prototip yöntemi oluşturdum 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>

Test sayfası


E.className dizini yerine sınıf listesini kullanmak istemenizin bir nedeni var mı? Perf daha az iyi gibi görünüyor
Ced

@Ced - sınıfları için binlerce öğeyi test etmiyorsanız, perf önemsizdir (muhtemelen tarayıcılarda gelecekte yeniden düzenlenecektir). kodun işlevselliğini açıkladığı için kullanımı daha zarif, ancak sonuçta, önemli değil, ne istersen yap :)
vsync

1
  1. Felix'in className ve aradığınız dizeyi çevrelemek için boşluk ekleme hilesi, öğelerin sınıfa sahip olup olmadığını belirlemek için doğru yaklaşımdır.

  2. Sınıfa göre farklı davranışlar elde etmek için, bir harita içinde işlev referanslarını veya işlevleri kullanabilirsiniz:

    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 in fns), fns haritasındaki tuşlar aracılığıyla yinelenir.
    • Fnsi'den sonra herhangi bir kopma olmaması, kodun bir eşleşme olduğunda yürütülmesine izin verir - böylece öğe, fi, sınıf1 ve sınıf2'ye sahipse, hem fn1 hem de fn2 yürütülür.
    • Bu yaklaşımın avantajı, her sınıf için yürütülecek kodun, switch ifadesindeki gibi keyfi olması; örneğinizde tüm vakalar benzer bir işlem gerçekleştirdi, ancak yarın her biri için farklı şeyler yapmanız gerekebilir.
    • Döngüde bir eşleşme bulunup bulunmadığını belirten bir durum değişkenine sahip olarak varsayılan durumu simüle edebilirsiniz.


1

Bu biraz kapalı, ancak geçişi tetikleyen bir etkinliğiniz varsa, sınıflar olmadan yapabilirsiniz:

<div id="classOne1"></div>
<div id="classOne2"></div>
<div id="classTwo3"></div>

Yapabilirsin

$('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, '')içindeki rakamları kaldırır id.

Biraz kurnazdır, ancak ekstra işlevler veya döngüler olmadan uzun anahtarlar için çalışır


1

Vanilya JavaScript ~ kullanarak belirli bir sınıfı varsa bir öğeyi daha hızlı ve kolay bir şekilde kontrol etmek için bu Codepen bağlantısına bakın!

hasClass (Vanilya JS)

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

1

Bu IE8 + 'da desteklenir.

Öncelikle IE10 + tarafından desteklenen yöntemi classListkullanıp kullanmadığımızı kontrol ederiz contains. IE9 veya 8'deysek, o kadar verimli olmayan ama özlü bir poli dolgu olan bir regex kullanmaya geri dönüyoruz.

if (el.classList) {
  el.classList.contains(className);
} else {
  new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}

Alternatif olarak babil ile derliyorsanız şunları kullanabilirsiniz: el.classList.contains(className);


0

Bunu dene:

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

1
Kelime sınırına dikkat edin. Ayrıca, örneğin bir sınıfınız varsa foo-barve aradığınızda da doğru olacaktır foo.
Felix Kling

1
Merhaba Jimy, bu yüzden bu \ b metakarakterini arıyordum ve sadece [ a-zA-Z0-9_] sözcük karakterleri olarak görüyor . Eksi karakter içeren bir sınıf adı için bu işe yaramaz .
Stano

0

Bence mükemmel çözüm bu olacak

if ($(this).hasClass("your_Class")) 
    alert("positive");            
else              
    alert("Negative");

8
1. "Düz JavaScript kullanma (jQuery değil)" 2. Parantez kullanın
nkmol

3 - Parantez kullanın
TheBlackBenzKid

0

hangi eleman şu anda '.bar' sınıfıdır? İşte başka bir çözüm ama size kalmış.

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 demosu

Tabii bu 1 basit element için sadece bir arama olduğu <img>( /Image/g) ancak böyle bir dizideki tüm koyabilirsiniz <li>olduğunu /LI/g, <ul>= /UL/gvs


0

Satır içi SVG öğeleri içinde sınıf adları bulmaya çalışan insanlar için cevaba eklemek için.

hasCLass()İşlevi şu şekilde değiştirin :

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

classNameÖzelliği kullanmak yerine getAttribute(), sınıf adını almak için yöntemi kullanmanız gerekir .


0

Web sitem için bu işlevleri oluşturdum, sadece vanilya javascript kullanıyorum, belki birine yardımcı olacaktır. Önce herhangi bir HTML öğesi almak için bir işlev oluşturdum:

//return an HTML element by ID, class or tag name
    var getElement = function(selector) {
        var elements = [];
        if(selector[0] == '#') {
            elements.push(document.getElementById(selector.substring(1, selector.length)));
        } else if(selector[0] == '.') {
            elements = document.getElementsByClassName(selector.substring(1, selector.length));
        } else {
            elements = document.getElementsByTagName(selector);
        }
        return elements;
    }

Ardından, kaldırılacak sınıfı ve öğenin seçicisini alan işlev:

var hasClass = function(selector, _class) {
        var elements = getElement(selector);
        var contains = false;
        for (let index = 0; index < elements.length; index++) {
            const curElement = elements[index];
            if(curElement.classList.contains(_class)) {
                contains = true;
                break;
            }
        }
        return contains;
    }

Şimdi şöyle kullanabilirsiniz:

hasClass('body', 'gray')
hasClass('#like', 'green')
hasClass('.button', 'active')

Umarım yardımcı olur.


0

İpucu: Projelerinizdeki jQuery bağımlılıklarını olabildiğince kaldırmaya çalışın - VanillaJS .

document.firstElementChild<html>etiketini döndürür, ardından classListözellik kendisine eklenen tüm sınıfları döndürür.

if(document.firstElementChild.classList.contains("your-class")){
    // <html> has 'your-class'
} else {
    // <html> doesn't have 'your-class'
}

-1

Benim için bunu başarmanın en zarif ve hızlı yolu:

function hasClass(el,cl){
   return !!el.className && !!el.className.match(new RegExp('\\b('+cl+')\\b'));
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.