1
votes

Comment puis-je retourner ou rendre nul tous les autres EventListeners si un autre est déclenché à l'aide de Javascript vanilla

Ce que j'essaie d'accomplir, c'est un code qui, lorsqu'un des boutons est cliqué, le bouton gagne les styles listés ci-dessous et tous les autres styles de bouton reviennent à null.

Je suppose que cela implique une instruction booléenne, mais je me trompe peut-être.

Vous verrez ci-dessous que j'essaie d'utiliser mon instruction "else if" pour établir que lorsque la cible de l'événement n'est pas égale à "bouton", pour tout remettre à zéro. Cependant, cela ne fonctionne clairement pas.

J'ai également essayé "! ==" et cela n'a pas fonctionné.

Évidemment, cela peut être fait en créant un Eventlistener unique à chaque bouton, mais je voulais comprendre comment faire cela de manière dynamique.

CSS:

var buttons = document.querySelectorAll('#button-container button');

buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    if (e.target === button) {
      e.target.style.backgroundColor = "blue";
      e.target.style.color = "orange";
    } else if (e.target != button) {
      e.target.style.backgroundColor = null;
      e.target.style.color = null;
    }
  })
})

Voici mon html:

<section id="button-container">
  <button>a</button>
  <button>b</button>
  <button>c</button>
  <button>d</button>
  <button>e</button>
</section>

Voici mon Javascript:

button {
  font-family: "sans-serif";
  margin: 1%;
  padding: 1%;
  cursor: pointer;
  font-size: 22px;
}


1 commentaires

Ne "gâchez" pas la propriété style . Ajoutez plutôt une classe (par exemple .active ) au bouton cliqué. Et avant cela, vous supprimez la classe du bouton ancien actif .


3 Réponses :


0
votes

Le moyen le plus simple est de se rappeler lequel est l'actuel dans une variable ...

let current = null;
buttons.forEach(button => {
    button.addEventListener("click", e => {
        if (current) {
            current.style.backgroundColor = "";
            current.style.color = "";
        }
        current = button;
        current.style.backgroundColor = "blue";
        current.style.color = "blue";
    });
});


0 commentaires

1
votes

Vous avez un écouteur par bouton, et donc, lorsque l'événement se produit, vous n'accédez qu'aux propriétés de ce bouton unique sur lequel l'événement s'est produit. Pourtant, vous auriez besoin de changer également quelque chose qui se rapporte au bouton précédemment marqué.

Je mettrais l'écouteur sur l'élément conteneur, vous n'avez donc besoin de créer qu'un seul écouteur, et vous n'avez pas besoin de le copier pour qu'il s'applique à chaque bouton séparément.

Deuxièmement, vous pouvez également utiliser une sorte d'élément d'ancrage que vous déplacez toujours avant le bouton qui devrait être "spécial", puis laissez le soin à un CSS intelligent de faire le reste.

Il est de toute façon préférable d'utiliser des classes CSS au lieu d'attributions de propriétés spécifiques de style dans votre code JS.

<section id="button-container">
  <button>a</button>
  <button>b</button>
  <button>c</button>
  <button>d</button>
  <button>e</button>
  <span class="marker" />
</section>
button {
  font-family: "sans-serif";
  margin: 1%;
  padding: 1%;
  cursor: pointer;
  font-size: 22px;
}

.marker+button {
  background-color: blue;
  color: orange;
}
var container = document.querySelector('#button-container');
var marker = document.querySelector('.marker');

container.addEventListener("click", function(e) {
  if (e.target.tagName === 'BUTTON') container.insertBefore(marker, e.target);
});


0 commentaires

1
votes

Au lieu de modifier directement le style , j'utiliserais plutôt une classe:

<section id="button-container">
  <button>a</button>
  <button>b</button>
  <button>c</button>
  <button>d</button>
  <button>e</button>
</section>

Lorsque vous cliquez sur un bouton, ajoutez le actif classe:

button {
  font-family: "sans-serif";
  margin: 1%;
  padding: 1%;
  cursor: pointer;
  font-size: 22px;
}

button.active {
  background-color: blue;
  color: orange;
}

Il ne nous reste plus qu'à ajouter une logique pour supprimer la classe active du bouton cliqué précédemment.

Nous pourrions soit passer en revue tous les boutons et supprimer la classe de tous:

var buttons = document.querySelectorAll('#button-container button');

buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    const activeButton = button.parentNode.querySelector("button.active");
    if (activeButton) {
      activeButton.classList.remove("active");
    }
    
    this.classList.add("active");
  })
})

Ou nous interroger le DOM pour le bouton actuellement "actif" et le supprimer de ce bouton uniquement:

const buttons = document.querySelector('#button-container');
const activeButtons = document.querySelector("#button-container").getElementsByClassName("active");

/* ... */

button.addEventListener("click", function(ev) {
  if (activeButtons.length) {
    activeButtons[0].classList.remove("active");  // there should always be only _one_ active button
  }

  this.classList.add("active");
});

ou nous utilisons le parentNode du bouton actuel pour "rechercher":

const activeButton = button.parentNode.querySelector("button.active");


3 commentaires

Merci de m'avoir aidé. Cela fonctionne à merveille. J'y travaille depuis quelques semaines et je comprends la plupart de ce que vous avez fait dans l'exemple de code, mais je n'arrive toujours pas à comprendre "if (activeButton)". Que dit cette déclaration?


Avec .querySelector ("button.active") nous "cherchons" un bouton qui a la classe active . querySelector () retournera soit le premier élément correspondant, soit null . Normalement, j'aurais dû vérifier si activeButton est null ( if (activeButton === null) ) mais parce que je suis paresseux (au moins parfois ^^) J'ai utilisé le fait que null est un valeur fausse et un objet (comme un nœud DOM renvoyé par .querySelector () ) est un valeur de vérité . (1/2)


Si .querySelector () trouve un élément qui correspond au sélecteur donné, alors activeButton sera un objet (= true) et if (activeButton) être identique à if (true) . S'il n'y a pas d'élément avec la classe donnée, alors activeButton vaut null (= falsy) et if (activeButton) serait le même comme if (false) (2/2)