J'ai le code suivant dans lequel j'ai des éléments HTML button.

Je veux que chaque fois que je click un bouton, la classe selected devrait basculer dans ce bouton.

Voici le code:

window.onload = function() {
  const [...btns] = document.getElementsByTagName('button');
  
  for(let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function() {
      if(this.className.split(' ').indexOf('selected') > -1) {
        this.className = this.className.split(' ').pop();
      } else {
        this.className = this.className.split(' ').push('selected').join(' ');
      }
      
      console.log(this.className);
    });
  }
}
button {
  outline: none;
  border: none;
  padding: 3px 7px;
  color: #FF4A3F;
  background: #E7E7E7;
  font: 500 16pt calibri;
  transform: scale(1, 0.95);
}
.selected {
  background: #353553;
  color: white;
}
<button>Home</button>
<button>Admission</button>
<button>Results</button>
<button>Curriculum</button>
<button>Contact us</button>

TypeError non capturé: this.className.split (...). Push (...). Join n'est pas une fonction

Qu'est ce que je fais mal?

1
user9090230 23 mai 2018 à 09:53

4 réponses

Meilleure réponse

Vous pouvez grandement simplifier la logique en utilisant à la place classList.toggle. Vous pouvez également utiliser querySelectorAll sur lequel vous pouvez forEach directement:

document.querySelectorAll('button').forEach(btn => {
  btn.addEventListener('click', () => {
    btn.classList.toggle('selected');
  });
});
button {
  outline: none;
  border: none;
  padding: 3px 7px;
  color: #FF4A3F;
  background: #E7E7E7;
  font: 500 16pt calibri;
  transform: scale(1, 0.95);
}
.selected {
  background: #353553;
  color: white;
}
<button>Home</button>
<button>Admission</button>
<button>Results</button>
<button>Curriculum</button>
<button>Contact us</button>

Le problème avec votre code d'origine est que push ne renvoie pas le tableau; il renvoie la longueur du tableau à la place, donc il n'est pas chaînable (malheureusement). Même chose avec pop().

Ajuster votre code pour qu'il fonctionne, en supposant que le dernier className sera toujours selected, ressemblerait à ceci:

window.onload = function() {
  const [...btns] = document.getElementsByTagName('button');
  
  for(let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function() {
      const classNameArr = this.className.split(' ');
      if(classNameArr.indexOf('selected') > -1) {
        classNameArr.pop();
        this.className = classNameArr.join(' ');
      } else {
        classNameArr.push('selected')
        this.className = classNameArr.join(' ');
      }
      console.log(this.className);
    });
  }
}
button {
  outline: none;
  border: none;
  padding: 3px 7px;
  color: #FF4A3F;
  background: #E7E7E7;
  font: 500 16pt calibri;
  transform: scale(1, 0.95);
}
.selected {
  background: #353553;
  color: white;
}
<button>Home</button>
<button>Admission</button>
<button>Results</button>
<button>Curriculum</button>
<button>Contact us</button>
1
CertainPerformance 23 mai 2018 à 07:02

Avez-vous pensé à utiliser jquery pour ce faire, ils ont une méthode remove et removeclass pour cela:

$("button").removeClass("selected");


$("button").addClass("selected");

J'espère que cela t'aides :)

0
sjdm 23 mai 2018 à 06:58
window.onload = function() {
  const [...btns] = document.getElementsByTagName('button');
  
  for(let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function() {
   this.classList.contains("selected")?this.classList.remove("selected"):this.classList.add("selected");
    });
  }
}
button {
  outline: none;
  border: none;
  padding: 3px 7px;
  color: #FF4A3F;
  background: #E7E7E7;
  font: 500 16pt calibri;
  transform: scale(1, 0.95);
}
.selected {
  background: #353553;
  color: white;
}
<button>Home</button>
<button>Admission</button>
<button>Results</button>
<button>Curriculum</button>
<button>Contact us</button>
0
Nishant Dixit 23 mai 2018 à 06:58

Le problème ici est que push ne renvoie pas le nouveau tableau, il renvoie la longueur du nouveau tableau. documents MDN pour push. Par conséquent, lorsque vous arrivez à join, il essaie de joindre un nombre, plutôt que le tableau que vous attendez.

Heureusement pour ce cas d'utilisation, il existe une méthode que vous pouvez utiliser directement - classList.toggle

document.querySelectorAll('button').forEach(btn => {
    btn.addEventListener('click', () => {
        btn.classList.toggle('selected');
    });
});
0
iblamefish 23 mai 2018 à 07:02