Wie füge ich einzelne Ereignis-Listener mit jquery .each () hinzu?
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:
- Warum das?
- 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
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>
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>
- Weil der Listener an den letzten Wert von $ toggle bindet.
- 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>