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.type
value
window
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 allebutton
Elementebindenund dietarget
Eigenschaft 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 toggle
in 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 one
und two
sind keine gültigen Werte für das type
Attribut. Verwenden Sie data
stattdessen 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>