Pregunta ¿Cómo puedo alternar la clase de un elemento en JavaScript puro?


Estoy buscando una manera de convertir este código jQuery (que se utiliza en la sección de menú de respuesta) a JavaScript puro.

Si es difícil de implementar, está bien usar otros frameworks de JavaScript.

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

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

gracias por adelantado


75
2017-09-18 19:39


origen


Respuestas:


Respuesta de 2014: classList.toggle() es el estándar y es compatible con la mayoría de los navegadores.

Los navegadores antiguos pueden usar use classlist.js para classList.toggle ():

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

Como un aparte, no deberías estar usando identificadores (ellos gotean globales en el JS window objeto)


131
2018-04-16 09:40



El método nativo más simple es Element.classList:

<div class="menu" onclick="javascript: this.classList.toggle('hidden-phone');">

15
2018-02-04 20:56



Echale un vistazo a éste ejemplo: 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;
}

10
2017-09-18 19:56



Éste también funciona en versiones anteriores de 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>


3
2018-01-15 17:37



Esto es quizás más sucinto:

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

2
2018-04-16 17:32



Aquí está la solución implementada con ES6

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

ejemplo de uso

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

1
2018-02-23 07:19



Pruebe esto (espero que funcione):

// 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
2017-11-15 07:51



Si desea alternar una clase a un elemento con solución nativa, puede intentar esta sugerencia. Lo he probado en diferentes casos, con o sin otras clases en el elemento, y creo que funciona bastante:

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

0
2018-06-26 14:30



Aquí hay un código para IE> = 9 usando split ("") en 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 += " ";
            }
        }
    }
}

-1
2017-07-05 13:21