¿Cómo puedo convertir este fragmento de código jQuery en JavaScript?

$('#element').click(function(){
    $(this).toggleClass('class1 class2')
});

Ya he probado los siguientes códigos, pero fue en vano.

El primero es:

var element = document.getElementById('element'),
    classNum = 0; // Supposing I know that the first time there will be that class
element.onmousedown = function() {
    if (classNum === 0) {
        this.classList.remove("class1");
        this.classList.add("class2");
        classNum = 1;
    }
    else if (classNum === 1) {
        this.classList.remove("class2");
        this.classList.add("class1");
        classNum = 0;
    }
}

La segunda es:

var element = document.getElementById('element'),
    classNum = 0; // Supposing I know that the first time there will be that class
element.onmousedown = function() {
    if (classNum === 0) {
        this.className -= "class1";
        this.classList += "class2";
        classNum = 1;
    }
    else if (classNum === 1) {
        this.classList -= "class2";
        this.classList += "class1";
        classNum = 0;
    }
}

Cualquier respuesta que no sugiera que me quede con jQuery será muy apreciada.

[EDITAR]

He probado todas sus soluciones, pero no he podido hacerlo bien. Creo que es porque no dije claramente que el elemento tiene múltiples clases así:

class="class1 class3 class4"

Y lo que quiero es básicamente reemplazar class1 con class2 y alternar entre ellos.

5
Angel Politis 11 may. 2016 a las 21:00

7 respuestas

La mejor respuesta

Actualización: En respuesta a los comentarios, classList.toggle es una solución de javascript puro . No tiene nada que ver con jQuery como implica un comentario. Si hay un requisito para admitir versiones antiguas de IE, entonces hay una cuña (pollyfill) en el enlace de MDN a continuación. Y esta cuña, si es necesario, es muy superior a la respuesta aceptada.

Usar classList.toggle ciertamente parece ser la solución más simple. Consulte también ¿Puedo usar classList para obtener asistencia para el navegador?

element.onclick = function() {
  'class1 class2'.split(' ').forEach(function(s) {
      element.classList.toggle(s);
  });
}

Ejecute el fragmento para probar

box.onclick = function() {
  'class1 class2'.split(' ').forEach(function(s) {
    box.classList.toggle(s);
    stdout.innerHTML = box.className;
  });
}


/* alternative 
box.onclick = function() {
  ['class1', 'class2'].forEach(function(s) {
    box.classList.toggle(s);
    stdout.innerHTML = box.className;
  });
}
*/
.class1 { background-color: red;}
.class2 { background-color: blue;}
.class3 { width: 100px; height: 100px; border: 1px black solid;}
click me:
<div id="box" class="class1 class3"></div>

<div id="stdout"></div>
5
Roberto 13 may. 2016 a las 20:56

ACTUALIZÓ MI RESPUESTA PARA APOYAR MÚLTIPLES CLASES POR ELEMENTO

https://jsfiddle.net/pwyncL8r/2/ Esto ahora permitirá que el elemento ya tenga < em> n y todavía intercambia solo una, conservando las otras clases.

HTML

<div id="div1" style="width: 100px; height: 100px;" class="backBlack left100"</div>
<input type="button" id="swapButton" value="Css Swap" />

CSS

.backBlack {
    background-color: black;
}

.backRed {
    background-color: red;
}

.left100 {
    margin-left: 100px;
}

JS

swapButton.onclick = function() {
    var curClassIsBlack = (' ' + document.getElementById("div1").className + ' ').indexOf(' backBlack ') > -1
    if (curClassIsBlack) {
        document.getElementById("div1").className =
        document.getElementById("div1").className.replace(/(?:^|\s)backBlack(?!\S)/g, '')
        document.getElementById("div1").className += " backRed";
    } else {
        document.getElementById("div1").className =
        document.getElementById("div1").className.replace(/(?:^|\s)backRed(?!\S)/g,'')
        document.getElementById("div1").className += " backBlack";
    }
}
0
programndial 12 may. 2016 a las 15:26

De: Es posible que no necesite jQuery

$(el).toggleClass(className);

Se sustituye por:

if (el.classList) {
  el.classList.toggle(className);
} else {
  var classes = el.className.split(' ');
  var existingIndex = classes.indexOf(className);

  if (existingIndex >= 0)
    classes.splice(existingIndex, 1);
  else
    classes.push(className);

  el.className = classes.join(' ');
}

Luego simplemente envuelva esa llamada de función dentro de un document.getElementById('elementId').click

2
Phil 11 may. 2016 a las 18:19

classNum es una variable local.

Cada vez que se llama al controlador de eventos, obtiene una nueva variable, que no tiene nada que ver con el valor de la última llamada.

Desea que sea una variable global.

O, mejor aún, marque classList.contains en su lugar.

2
SLaks 11 may. 2016 a las 18:02

Puedes usar classList, pero solo es compatible con IE 10+

Demo

  var eles = document.querySelectorAll('#element');
  var classNames = 'one two';

  for(var i = 0; i < eles.length; i ++){
    eles[i].onclick = function(e){
      toggleClass.call(this, classNames);
    }
  }

  function toggleClass(names){
    var sp = names.split(' ');
    for(var i = 0; i < sp.length; i++){
      this.classList.toggle(sp[i]);
    }

  }
1
MarkoCen 11 may. 2016 a las 18:18

Su código está cerca, pero su variable classNum no es iterativa. Prueba esto:

var element = document.getElementById("element");
var numCount = 0;

element.addEventListener('click', function() {
	if (numCount === 0) {
		this.className = "";
        this.className += " class1";
        numCount++;
	} else {
        this.className = "";
		this.className += " class2";
        numCount = 0;
	}
});
.class1 {
  color: red;
}
.class2 {
  color: blue;  
}
<div id="element">click me</div>
1
Sean Henderson 11 may. 2016 a las 18:14

Ver violín: https://jsfiddle.net/2ch8ztdk/

var s = document.getElementById('element');
s.onclick=function(){
  if(s.className == "class1"){
    s.className = "class2"
  } else {
    s.className = "class1"
  }
}
1
Timothy Kanski 11 may. 2016 a las 18:08