Comment ajouter des écouteurs d'événements individuels à l'aide de jquery .each ()?
J'ai une configuration simple: deux boutons avec des valeurs différentes. Je veux utiliser la fonction .each () de jquery pour ajouter un écouteur d'événement de clic à chacun des boutons qui enregistre simplement les valeurs de chaque bouton. Mais d'une manière ou d'une autre, lors de l'utilisation de .each (), jquery écrase le gestionnaire de clics pour le (s) bouton (s) précédent (s). Cela me laisse avec deux questions:
- Pourquoi donc?
- Comment ajouter des écouteurs d'événements individuels à une collection d'objets jquery?
Voir le code ci-dessous
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => { $(`button[toggle]`).each((_, button) => {
let $toggle = $(button);
type = $toggle.attr("type"); value = $toggle.attr("value");
$toggle.on("click", () => {
console.log(type, value);
});
});
});
</script>
</head>
<body>
<div>
<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>
</div>
</body>
</html>
Réponses
Le problème dans votre code est que vous avez implicitement déclaré les variables type
et value
, donc elles sont dans la window
portée. En tant que tel, chaque itération suivante écrase les valeurs de sorte que seules les valeurs finales soient vues après la fin de la boucle.
Pour résoudre ce problème, définissez les variables dans la boucle:
$(() => { $(`button[toggle]`).each((_, button) => {
let $toggle = $(button);
let type = $toggle.attr("type"); let value = $toggle.attr("value");
$toggle.on("click", () => {
console.log(type, value);
});
});
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>
</div>
Cependant , vous n'avez pas du tout besoin de laeach()
boucle. Vous pouvez résoudre le problème et améliorer la qualité du code en liant le même gestionnaire d'événements à tous lesbutton
éléments et en utilisant latarget
propriété de l'événement qui est déclenché pour accéder à leurs attributs.
En outre, notez que l'ajout de vos propres attributs non standard, toggle
dans ce cas, peut entraîner des problèmes dans l'interface utilisateur et le JS. Une meilleure approche consiste à utiliser une classe pour regrouper les éléments.
Enfin, one
et two
ne sont pas des valeurs valides pour l' type
attribut. Utilisez data
plutôt un attribut pour attacher vos propres métadonnées personnalisées à un élément.
Cela dit, essayez ceci:
jQuery($ => {
$('.toggle').on('click', e => { let $toggle = $(e.target); let type = $toggle.data("type");
let value = $toggle.prop("value");
console.log(type, value);
});
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<div>
<button class="toggle" data-type="one" value="true">One</button>
<button class="toggle" data-type="two" value="false">Two</button>
</div>
utiliser $(this)
à l'intérieur du rappel de clic
$(() => {
$(`button[toggle]`).each((_, button) => { $(button).on("click", function(){
type = $(this).attr("type"); value = $(this).attr("value");
console.log(type, value);
});
});
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>
Et aussi pas besoin de mentionner à l'intérieur de chaque rappel. Vous pouvez appeler de manière normale comme ci-dessous
$(() => { $(`button[toggle]`).on("click", function(){
type = $(this).attr("type"); value = $(this).attr("value");
console.log(type, value);
});
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>
- Parce que l'auditeur se lie à la dernière valeur de $ toggle.
- En créant et en exécutant une nouvelle fonction comme indiqué dans l'extrait de code.
Mieux expliqué dans cette question .
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
$(`button[toggle]`).each((_, button) => { let $toggle = $(button); type = $toggle.attr("type");
value = $toggle.attr("value"); $toggle.on("click", ((type, value) => {
return () => {
console.log(type, value);
};
})(type, value));
});
});
</script>
</head>
<body>
<div>
<button toggle type="one" value="true">One</button>
<button toggle type="two" value="false">Two</button>
</div>
</body>
</html>