Wie füge ich einzelne Ereignis-Listener mit jquery .each () hinzu?

Jan 08 2021

Ich habe ein einfaches Setup: Zwei Tasten mit unterschiedlichen Werten. Ich möchte die Funktion .each () von jquery verwenden, um jeder Schaltfläche einen Klickereignis-Listener hinzuzufügen, der einfach die Werte jeder Schaltfläche protokolliert. Aber irgendwie überschreibt jquery bei Verwendung von .each () den Klick-Handler für die vorherigen Schaltflächen. Dies lässt mich mit zwei Fragen zurück:

  1. Warum das?
  2. Wie können einzelne Ereignis-Listener zu einer Sammlung von Abfrageobjekten hinzugefügt werden?

Siehe Code unten

  <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>

Antworten

1 RoryMcCrossan Jan 08 2021 at 20:14

Das Problem in Ihrem Code besteht darin, dass Sie die Variablen und implizit deklariert haben , sodass sie im Gültigkeitsbereich liegen. Daher überschreibt jede folgende Iteration die Werte, sodass nach dem Ende der Schleife nur die endgültigen Werte angezeigt werden.typevaluewindow

Um dies zu beheben, definieren Sie die Variablen innerhalb der Schleife:

$(() => { $(`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>

Sie benötigen dieeach()Schleife jedoch überhaupt nicht. Sie können das Problem beheben und die Codequalität verbessern, indem Sie denselben Ereignishandler an allebuttonElementebindenund dietargetEigenschaft des Ereignisses verwenden, das ausgelöst wird, um auf deren Attribute zuzugreifen.

Beachten Sie außerdem, dass das Hinzufügen eigener nicht standardmäßiger Attribute togglein diesem Fall zu Problemen in der Benutzeroberfläche und in JS führen kann. Ein besserer Ansatz besteht darin, eine Klasse zum Gruppieren der Elemente zu verwenden.

Schließlich oneund twosind keine gültigen Werte für das typeAttribut. Verwenden Sie datastattdessen ein Attribut, um Ihre eigenen benutzerdefinierten Metadaten an ein Element anzuhängen.

Versuchen Sie nach all dem Folgendes:

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

Verwenden Sie $(this)innerhalb des Klick-Rückrufs

$(() => {
  $(`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>

Und auch keine Notwendigkeit, in jedem Rückruf zu erwähnen. Sie können auf normale Weise wie unten anrufen

$(() => { $(`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. Weil der Listener an den letzten Wert von $ toggle bindet.
  2. Durch Erstellen und Ausführen einer neuen Funktion, wie im Snippet gezeigt.

In dieser Frage besser erklärt .

<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>