Bagaimana cara mengganti kelas elemen dalam JavaScript murni?

128

Saya mencari cara untuk mengubah kode jQuery ini (yang digunakan di bagian menu responsif) menjadi JavaScript murni.

Jika sulit untuk diimplementasikan, tidak apa-apa untuk menggunakan framework JavaScript lainnya.

$('.btn-navbar').click(function()
{
    $('.container-fluid:first').toggleClass('menu-hidden');
    $('#menu').toggleClass('hidden-phone');

    if (typeof masonryGallery != 'undefined') 
        masonryGallery();
});
max imax
sumber
11
document.getElementById("menu").classList.toggle("hidden-phone"):-)
Bergi
classList tidak didukung oleh beberapa browser: caniuse.com/classlist
Kevin Whitaker
6
Hai @max, sudah mau pilih jawaban?
mikemaccana

Jawaban:

213

Jawaban 2014 : classList.toggle()adalah standar dan didukung oleh sebagian besar browser .

Browser lama dapat menggunakan penggunaan classlist.js untuk classList.toggle () :

var menu = document.querySelector('.menu') // Using a class instead, see note below.
menu.classList.toggle('hidden-phone');

Selain itu, Anda tidak boleh menggunakan ID (ID tersebut membocorkan global ke dalam windowobjek JS ).

mikemaccana
sumber
jika kita tidak bisa menggunakan ID, lalu bagaimana caranya?
Goku
tetapi, kemudian kita akan memiliki kuantitas kelas yang sama, bukan ID lama, dan menggunakan sesuatu seperti var myList = document.getElementsByClassName ("abc")?
Goku
1
Kelas @goku tidak muncul di bawah objek jendela. Hanya ID yang melakukannya. Lihat 2ality.com/2012/08/ids-are-global.html
mikemaccana
1
Didukung oleh IE10 dan IE11 kecuali untuk parameter kedua
Di bawah Radar
1
Terima kasih banyak! Ini bekerja sekarang :) Saya menambahkan lebih banyak opsi untuk loop: var All = document.querySelectorAll ('. Menu'); untuk (var i = 0; i <All.length; i ++) {All [i] .classList.toggle ('hidden-phone'); }
Trem Biru
11

Berikut adalah solusi yang diimplementasikan dengan ES6

const toggleClass = (el, className) => el.classList.toggle(className);

contoh penggunaan

toggleClass(document.querySelector('div.active'), 'active'); // The div container will not have the 'active' class anymore
Gor
sumber
3
ES6 bagus, tetapi solusi ini hanya menggunakan 'document.querySelector' dan 'element.classList.toggle' sesuai jawaban lain yang ada.
mikemaccana
Tidak ada solusi yang valid jika "berorientasi vendor", Internet berorientasi pada standar terbuka .
Peter Krauss
ini bukan solusi untuk banyak file. tidak bekerja dengan querySelectorAll (setidaknya di FF) jadi bagi mereka yang ingin beralih kelas pada beberapa elemen baca di :-) (Saya tidak membaca pada awalnya - demikian komentar saya!)
kev1807
9

Lihat contoh ini: JS Fiddle

function toggleClass(element, className){
    if (!element || !className){
        return;
    }

    var classString = element.className, nameIndex = classString.indexOf(className);
    if (nameIndex == -1) {
        classString += ' ' + className;
    }
    else {
        classString = classString.substr(0, nameIndex) + classString.substr(nameIndex+className.length);
    }
    element.className = classString;
}
Eugene Yastrebov
sumber
9
Bagaimana jika saya memiliki kelas setelah "merah" bernama "redOther"?
Tiffany Lowe
4

Yang ini juga berfungsi di versi IE sebelumnya.

function toogleClass(ele, class1) {
  var classes = ele.className;
  var regex = new RegExp('\\b' + class1 + '\\b');
  var hasOne = classes.match(regex);
  class1 = class1.replace(/\s+/g, '');
  if (hasOne)
    ele.className = classes.replace(regex, '');
  else
    ele.className = classes + class1;
}
.red {
  background-color: red
}
div {
  width: 100px;
  height: 100px;
  margin-bottom: 10px;
  border: 1px solid black;
}
<div class="does red redAnother " onclick="toogleClass(this, 'red')"></div>

<div class="does collapse navbar-collapse " onclick="toogleClass(this, 'red')"></div>

RRK
sumber
\bbatas kata tidak konsisten dengan pemisah nama kelas css. misalnya tidak berfungsi jika nama kelas berisi tanda hubung ("-") char: btn, btn-red keduanya akan cocok '\\b' + 'btn' + '\\b'!!
S. Serpooshan
3

Ini mungkin lebih ringkas:

function toggle(element, klass) {
  var classes = element.className.match(/\S+/g) || [],
      index = classes.indexOf(klass);

  index >= 0 ? classes.splice(index, 1) : classes.push(klass);
  element.className = classes.join(' ');
}
mushishi78.dll
sumber
0

Coba ini (semoga berhasil):

// mixin (functionality) for toggle class 
function hasClass(ele, clsName) {
    var el = ele.className;
    el = el.split(' ');
    if(el.indexOf(clsName) > -1){
        var cIndex = el.indexOf(clsName);
        el.splice(cIndex, 1);
        ele.className = " ";
        el.forEach(function(item, index){
          ele.className += " " + item;
        })
    }
    else {
        el.push(clsName);
        ele.className = " ";
        el.forEach(function(item, index){
          ele.className += " " + item;
        })
    }
}

// get all DOM element that we need for interactivity.

var btnNavbar =  document.getElementsByClassName('btn-navbar')[0];
var containerFluid =  document.querySelector('.container-fluid:first');
var menu = document.getElementById('menu');

// on button click job
btnNavbar.addEventListener('click', function(){
    hasClass(containerFluid, 'menu-hidden');
    hasClass(menu, 'hidden-phone');
})`enter code here`
Rajbir Sharma
sumber
0

Berikut adalah kode untuk IE> = 9 dengan menggunakan split ("") pada className:

function toggleClass(element, className) {
    var arrayClass = element.className.split(" ");
    var index = arrayClass.indexOf(className);

    if (index === -1) {
        if (element.className !== "") {
            element.className += ' '
        }
        element.className += className;
    } else {
        arrayClass.splice(index, 1);
        element.className = "";
        for (var i = 0; i < arrayClass.length; i++) {
            element.className += arrayClass[i];
            if (i < arrayClass.length - 1) {
                element.className += " ";
            }
        }
    }
}
P. Lefèvre
sumber
0

Jika Anda ingin mengalihkan kelas menjadi elemen menggunakan solusi asli, Anda dapat mencoba saran ini. Saya telah mencicipinya dalam kasus yang berbeda, dengan atau tanpa kelas lain ke dalam elemen, dan saya pikir itu bekerja cukup banyak:

(function(objSelector, objClass){
   document.querySelectorAll(objSelector).forEach(function(o){
      o.addEventListener('click', function(e){
        var $this = e.target,
            klass = $this.className,
            findClass = new RegExp('\\b\\s*' + objClass + '\\S*\\s?', 'g');

        if( !findClass.test( $this.className ) )
            if( klass ) 
                $this.className = klass + ' ' + objClass;
            else 
                $this.setAttribute('class', objClass);
        else 
        {
            klass = klass.replace( findClass, '' );
            if(klass) $this.className = klass;
            else $this.removeAttribute('class');
        }
    });
  });
})('.yourElemetnSelector', 'yourClass');
Christiyan
sumber