Come si attiva la classe di un elemento in JavaScript puro?


128

Sto cercando un modo per convertire questo codice jQuery (che viene utilizzato nella sezione del menu reattivo) in JavaScript puro.

Se è difficile da implementare, va bene usare altri framework JavaScript.

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

    if (typeof masonryGallery != 'undefined') 
        masonryGallery();
});


11
document.getElementById("menu").classList.toggle("hidden-phone"):-)
Bergi

classList non è supportato da alcuni browser: caniuse.com/classlist
Kevin Whitaker

6
Ehi @max, vuoi già scegliere una risposta?
mikemaccana

Risposte:


213

Risposta del 2014 : classList.toggle()è lo standard ed è supportato dalla maggior parte dei browser .

I browser meno recenti possono utilizzare classlist.js per classList.toggle () :

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

Per inciso, non dovresti usare gli ID ( perdono i valori globali windownell'oggetto JS ).


se non possiamo usare gli ID, come possiamo farlo?
Goku

ma allora avremo la stessa quantità di classi invece dei vecchi ID, e useremo qualcosa come var myList = document.getElementsByClassName ("abc")?
Goku

1
Le classi @goku non vengono visualizzate sotto l'oggetto finestra. Solo gli ID lo fanno. Vedi 2ality.com/2012/08/ids-are-global.html
mikemaccana

1
Supportato da IE10 e IE11 eccetto per il secondo parametro
Sotto il radar

1
Grazie mille! Ora funziona :) Aggiungo più opzioni per loop: var All = document.querySelectorAll ('. Menu'); for (var i = 0; i <All.length; i ++) {All [i] .classList.toggle ('hidden-phone'); }
Blue Tram

11

Ecco la soluzione implementata con ES6

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

esempio di utilizzo

toggleClass(document.querySelector('div.active'), 'active'); // The div container will not have the 'active' class anymore

3
ES6 è ottimo, ma questa soluzione utilizza semplicemente "document.querySelector" e "element.classList.toggle" per le altre risposte esistenti.
mikemaccana

Nessuna soluzione è valida se è "vendor oriented", Internet è orientata agli standard aperti .
Peter Krauss,

questa non è una soluzione per una moltitudine di file. non funziona con querySelectorAll (almeno in FF) quindi per coloro che cercano di alternare le classi su più elementi continua a leggere :-) (non ho letto all'inizio - quindi il mio commento!)
kev1807

9

Dai un'occhiata a questo esempio: 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;
}

9
E se avessi una classe dopo "rosso" denominata "rossoAltro"?
Tiffany Lowe

4

Questo funziona anche nelle versioni precedenti di IE.

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>


\bil confine della parola non è coerente con i separatori del nome della classe CSS. per esempio non funziona se il nome della classe contiene un trattino ("-") char: btn, btn-red corrisponderanno entrambi '\\b' + 'btn' + '\\b'!!
S.Serpooshan

3

Questo è forse più succinto:

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(' ');
}

0

Prova questo (si spera che funzioni):

// 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`

0

Ecco un codice per IE> = 9 utilizzando split ("") su 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 += " ";
            }
        }
    }
}

0

Se vuoi trasformare una classe in un elemento usando una soluzione nativa, potresti provare questo suggerimento. L'ho assaggiato in diversi casi, con o senza altre classi sull'elemento, e penso che funzioni più o meno:

(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');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.