Apa fungsi "hasClass" dengan JavaScript biasa?

313

Bagaimana Anda melakukan jQuery hasClassdengan JavaScript biasa? Sebagai contoh,

<body class="foo thatClass bar">

Apa cara JavaScript untuk bertanya jika <body>sudah thatClass?

Kyle
sumber
Saya kira Anda harus mengurai classproperti (yang dalam hal beberapa kelas akan memiliki beberapa nama kelas dalam urutan acak yang dipisahkan oleh spasi) dan memeriksa apakah nama kelas Anda ada di dalamnya. Tidak terlalu sulit, tetapi masih sangat merepotkan jika tidak untuk tujuan pembelajaran :)
Pekka
7
tidak tahu apakah saya terlambat ke pesta tetapi situs bagus yang memberikan alternatif fungsi jQuery adalah youmightnotneedjquery.com
ithil

Jawaban:

116

Anda dapat memeriksa apakah element.classNamecocok /\bthatClass\b/.
\bcocok dengan istirahat kata.

Atau, Anda dapat menggunakan implementasi jQuery sendiri:

var className = " " + selector + " ";
if ( (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(" thatClass ") > -1 ) 

Untuk menjawab pertanyaan Anda yang lebih umum, Anda dapat melihat kode sumber jQuery di github atau pada sumber untuk hasClasskhususnya di penampil sumber ini .

Slaks
sumber
6
+1 untuk implementasi jQuery (karena telah melihat ke atas (apakah ini bahasa Inggris yang tepat?) Apa yang rclasssebenarnya;))
Felix Kling
6
Tidak \bcocok dengan "thatClass-anotherClass"?
Matthew Crumley
3
hanya untuk kelengkapan: rclass dalam versi terbaru adalah "/ [\ n \ t \ r] / g" (\ r ditambahkan)
Felix Schwarz
4
@ Felikschwarz benar, di jQuery saat ini regexp telah diperbarui /[\t\r\n\f]/g. Juga bagus untuk menyebutkan bahwa /\bclass\b/bisa gagal untuk nama-nama kelas dengan -tanda minus (selain itu berfungsi baik), itu sebabnya implementasi jQuery lebih baik dan lebih dapat diandalkan. Misalnya: /\bbig\b/.test('big-text')mengembalikan true, bukan false yang diharapkan.
Stano
996

Cukup gunakan classList.contains():

if (document.body.classList.contains('thatClass')) {
    // do some stuff
}

Penggunaan lain dari classList:

document.body.classList.add('thisClass');
// $('body').addClass('thisClass');

document.body.classList.remove('thatClass');
// $('body').removeClass('thatClass');

document.body.classList.toggle('anotherClass');
// $('body').toggleClass('anotherClass');

Dukungan Browser:

  • Chrome 8.0
  • Firefox 3.6
  • IE 10
  • Opera 11.50
  • Safari 5.1

classList Dukungan Browser

Damien
sumber
5
Ini tidak didukung di IE8 . IE8 dapat mengambil .classListsebagai string, tetapi tidak akan mengenali metode yang lebih modern seperti.classList.contains()
iono
7
@iono Dalam deskripsi implementasi Element.classList dari MDN ada shim yang memperluas dukungan untuk perilaku ini ke IE8 developer.mozilla.org/en-US/docs/Web/API/Element/classList
James
3
Saya setuju dengan @AlexanderWigmore, ini sangat membantu dan sederhana.
Jacques Olivier
Pilih ini. Ini adalah cara yang jauh lebih bersih untuk kelas kueri
user2190488
@ SLaks ini harus diperbarui untuk menjadi jawaban yang sudah diterima.
Umur Karagöz
35

Yang paling efektif adalah liner itu

  • mengembalikan boolean (sebagai lawan dari jawaban Orbling)
  • Tidak mengembalikan false positive saat mencari thisClasselemen yang dimiliki class="thisClass-suffix".
  • kompatibel dengan setiap browser hingga setidaknya IE6

function hasClass( target, className ) {
    return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
}
gua
sumber
28

Atribut yang menyimpan kelas yang digunakan adalah className.

Jadi bisa dibilang:

if (document.body.className.match(/\bmyclass\b/)) {
    ....
}

Jika Anda menginginkan lokasi yang menunjukkan kepada Anda bagaimana jQuery melakukan segalanya, saya sarankan:

http://code.jquery.com/jquery-1.5.js

Orbling
sumber
1
Luar biasa. The matchAtribut datang berguna lagi! Benarkah jQuery melakukan sesuatu yang lebih dari yang dimungkinkan dalam JavaScript ?! Jika tidak, jQuery hanyalah beban singkat yang tidak perlu.
animaacija
1
Ini juga cocok myclass-something, seperti \bcocok dengan tanda hubung.
Marc Durdin
1
@animaacija Semua perpustakaan / plugin javascript pada dasarnya adalah singkatan javascript karena dibangun dengan javascript. Masalahnya adalah: singkatan selalu diperlukan. Jangan pernah menemukan kembali roda.
Edwin Stoteler
Ini solusi hebat!
Manuel Abascal
28

// 1. Use if for see that classes:

if (document.querySelector(".section-name").classList.contains("section-filter")) {
  alert("Grid section");
  // code...
}
<!--2. Add a class in the .html:-->

<div class="section-name section-filter">...</div>

StiveAZ
sumber
4
@regregdiesel: jangan mengecilkan jawaban! Solusi baru untuk masalah umum lebih dari diterima.
raveren
2
@Raveren sementara solusi baru untuk masalah lama disambut, jawaban khusus ini tidak membawa hal baru. Itu hanya menambah kebisingan pada pertanyaan ini.
Emile Bergeron
1
@raveren Ini bukan solusi baru, ini sama dengan jawaban ini tetapi dengan informasi yang lebih sedikit.
Dana Gugatan Monica
13

Fungsi hasClass:

HTMLElement.prototype.hasClass = function(cls) {
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] == cls) {
            return true;
        }
    }
    return false;
};

fungsi addClass:

HTMLElement.prototype.addClass = function(add) {
    if (!this.hasClass(add)){
        this.className = (this.className + " " + add).trim();
    }
};

fungsi removeClass:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.replace(/\s{2,}/g, ' ').split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName.trim();
};
Gawin
sumber
11

Saya menggunakan solusi sederhana / minimal, satu baris, lintas browser, dan bekerja dengan browser lawas juga:

/\bmyClass/.test(document.body.className) // notice the \b command for whole word 'myClass'

Metode ini hebat karena tidak memerlukan polyfill dan jika Anda menggunakannyaclassList itu jauh lebih baik dalam hal kinerja. Setidaknya untuk saya.

Pembaruan: Saya membuat polyfill kecil yang merupakan solusi menyeluruh yang saya gunakan sekarang:

function hasClass(element,testClass){
  if ('classList' in element) { return element.classList.contains(testClass);
} else { return new Regexp(testClass).exec(element.className); } // this is better

//} else { return el.className.indexOf(testClass) != -1; } // this is faster but requires indexOf() polyfill
  return false;
}

Untuk manipulasi kelas lainnya, lihat file lengkap di sini .

terima kasih
sumber
2
Apakah perjalanan ini akan lebih dari satu kelas notmyClassHere?
Teepeemm
2
Anda juga dapat bertanya apakah kelas Anda tidak ada di sana dan !/myClass/.test(document.body.className)perhatikan juga !simbolnya.
thednp
1
Saya tidak berbicara tentang meniadakan pertanyaan. Saya berpikir bahwa fungsi Anda tidak benar akan mengembalikan true jika nama kelasnya thisIsmyClassHere.
Teepeemm
1
Saya hanya menebak itu yang Anda tanyakan, tidak mengerti persis apa yang Anda butuhkan, tetapi sudahkah Anda mencobanya dan gagal mengembalikan benar / salah sebagaimana mestinya?
thednp
2
Ini tidak sempurna karena bukan bukti substring. Misal ketika document.body.className = 'myClass123', lalu /myClass/.test(document.body.className) mengembalikan true ...
Zbigniew Wiadro
9

solusi yang baik untuk ini adalah bekerja dengan classList dan mengandung.

saya melakukannya seperti ini:

... for ( var i = 0; i < container.length; i++ ) {
        if ( container[i].classList.contains('half_width') ) { ...

Jadi, Anda perlu elemen Anda dan periksa daftar kelas. Jika salah satu kelas sama dengan yang Anda cari akan mengembalikan true jika tidak, itu akan kembali salah!

Bastian Fießinger
sumber
6

Gunakan sesuatu seperti:

Array.prototype.indexOf.call(myHTMLSelector.classList, 'the-class');
Alejandro Nanez
sumber
3
Bukankah ini setara dengan myHTMLSelector.classList.indexOf('the-class')? Bukankah Anda juga ingin >=0pada akhirnya?
Teepeemm
5
Apa gunanya menggunakan [].indexOfjika classListmemiliki containsmetode?
Oriol
@Terima tuh. myHTMLSelector.classList.indexOf('the-class')mengembalikan kesalahan itu myHTMLSelector.classList.indexOf is not a functionkarena myHTMLSelector.classListbukan array. Tapi saya kira ketika menyebutnya menggunakan Array.prototypebeberapa konversi terjadi. Ini mungkin mendukung browser yang lebih lama, walaupun containsmemiliki dukungan yang sangat baik.
Ehsan88
4
if (document.body.className.split(/\s+/).indexOf("thatClass") !== -1) {
    // has "thatClass"
}
Alexandr Karbivnichiy
sumber
2

Fungsi 'hasClass' ini berfungsi di IE8 +, FireFox dan Chrome:

hasClass = function(el, cls) {
    var regexp = new RegExp('(\\s|^)' + cls + '(\\s|$)'),
        target = (typeof el.className === 'undefined') ? window.event.srcElement : el;
    return target.className.match(regexp);
}
manufosela
sumber
1

Yah semua jawaban di atas cukup bagus tapi di sini ada fungsi sederhana kecil yang saya lakukan. Ini bekerja dengan cukup baik.

function hasClass(el, cn){
    var classes = el.classList;
    for(var j = 0; j < classes.length; j++){
        if(classes[j] == cn){
            return true;
        }
    }
}
baru saja
sumber
3
Apa gunanya iterasi jika classListpunya containsmetode?
Oriol
1

Apa pendapat Anda tentang pendekatan ini?

<body class="thatClass anotherClass"> </body>

var bodyClasses = document.querySelector('body').className;
var myClass = new RegExp("thatClass");
var trueOrFalse = myClass.test( bodyClasses );

https://jsfiddle.net/5sv30bhe/

Marian07
sumber
2
Saya pikir Anda mencampur nama variabel Anda (aktif === myClass?). Tetapi bukankah pendekatan ini akan memberikan hasil positif palsu class="nothatClassIsnt"?
Teepeemm
0

Inilah cara paling sederhana:

var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
    if (allElements[i].hasAttribute("class")) {
         //console.log(allElements[i].className);
         if (allElements[i].className.includes("_the _class ")) { 
              console.log("I see the class");
         }
    }
}
Komunitas Ans
sumber