Comment ajouter des écouteurs d'événements individuels à l'aide de jquery .each ()?

Jan 08 2021

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:

  1. Pourquoi donc?
  2. 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

1 RoryMcCrossan Jan 08 2021 at 20:14

Le problème dans votre code est que vous avez implicitement déclaré les variables typeet value, donc elles sont dans la windowporté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 latargetproprié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, toggledans 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, oneet twone sont pas des valeurs valides pour l' typeattribut. Utilisez dataplutô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>

1 prasanth Jan 08 2021 at 20:10

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>

Kostas Jan 08 2021 at 20:11
  1. Parce que l'auditeur se lie à la dernière valeur de $ toggle.
  2. 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>