Jak dodać poszczególne detektory zdarzeń za pomocą jquery .each ()?
Mam prostą konfigurację: dwa przyciski z różnymi wartościami. Chcę użyć funkcji .each () z jquery, aby dodać detektor zdarzeń kliknięcia do każdego z przycisków, który po prostu rejestruje wartości każdego przycisku. Ale w jakiś sposób podczas używania .each () jquery nadpisuje moduł obsługi kliknięcia dla poprzedniego przycisku (ów). Pozostają mi dwa pytania:
- Dlaczego?
- Jak dodać poszczególne detektory zdarzeń do kolekcji obiektów jquery?
Zobacz kod poniżej
<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>
Odpowiedzi
Problem w twoim kodzie polega na tym, że niejawnie zadeklarowałeś zmienne type
i value
, więc są one window
objęte zakresem. W związku z tym każda następna iteracja nadpisuje wartości, tak że po zakończeniu pętli widoczne są tylko wartości końcowe.
Aby to naprawić, zdefiniuj zmienne w pętli:
$(() => { $(`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>
Jednakeach()
pętla w ogólenie jest potrzebna. Możesz rozwiązać problem i poprawić jakość kodu, wiążąc tę samą procedurę obsługi zdarzeń ze wszystkimibutton
elementami i używająctarget
właściwości zdarzenia, które jest wywoływane, w celu uzyskania dostępu do ich atrybutów.
Ponadto pamiętaj, że dodanie własnych niestandardowych atrybutów toggle
w tym przypadku może prowadzić do problemów w interfejsie użytkownika i JS. Lepszym podejściem jest użycie klasy do grupowania elementów.
Wreszcie one
i two
nie są prawidłowymi wartościami type
atrybutu. data
Zamiast tego użyj atrybutu, aby dołączyć własne niestandardowe metadane do elementu.
Biorąc to wszystko pod uwagę, spróbuj tego:
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>
użyj $(this)
wewnątrz wywołania zwrotnego kliknięcia
$(() => {
$(`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>
A także nie trzeba wspominać w każdym wywołaniu zwrotnym. Możesz zadzwonić w normalny sposób, jak poniżej
$(() => { $(`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>
- Ponieważ detektor wiąże się z ostatnią wartością $ toggle.
- Tworząc i uruchamiając nową funkcję, jak pokazano we fragmencie.
Wyjaśniono lepiej w tym pytaniu .
<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>