jquery .each ()를 사용하여 개별 이벤트 리스너를 추가하는 방법은 무엇입니까?
간단한 설정 : 다른 값을 가진 두 개의 버튼. jquery의 .each () 함수를 사용하여 각 버튼의 값을 기록하는 각 버튼에 클릭 이벤트 리스너를 추가하고 싶습니다. 그러나 .each ()를 사용할 때 jquery는 이전 버튼에 대한 클릭 핸들러를 덮어 씁니다. 이로 인해 두 가지 질문이 남습니다.
- 왜 그런 겁니까?
- jquery 객체 모음에 개별 이벤트 리스너를 어떻게 추가합니까?
아래 코드 참조
<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>
답변
코드의 문제 는 및 변수를 암시 적으로 선언 했기 때문에 범위 내에 있습니다. 따라서 이후의 각 반복은 값을 덮어 쓰므로 루프가 끝난 후 최종 값만 표시됩니다.type
value
window
이를 수정하려면 루프 내 에서 변수를 정의하십시오 .
$(() => { $(`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>
그러나each()
루프가 전혀 필요하지 않습니다. 동일한 이벤트 핸들러를 모든button
요소에 바인딩하고target
해당 속성에 액세스하기 위해 발생하는 이벤트의속성을사용하여문제를 해결하고 코드 품질을 개선 할 수 있습니다.
또한 toggle
이 경우 고유 한 비표준 속성을 추가 하면 UI 및 JS에 문제가 발생할 수 있습니다. 더 나은 접근 방식은 클래스를 사용하여 요소를 그룹화하는 것입니다.
마지막으로, one
및 two
에 대한 유효한 값없는 type
속성입니다. 용도 data
요소에 사용자 정의 메타 데이터를 연결하는 대신 속성을.
말한대로 다음을 시도하십시오.
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>
$(this)
클릭 콜백 내부에서 사용
$(() => {
$(`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>
또한 각 콜백 내부에 언급 할 필요가 없습니다. 아래와 같이 정상적인 방법으로 전화 할 수 있습니다.
$(() => { $(`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>
- 리스너는 $ toggle의 마지막 값에 바인딩하기 때문입니다.
- 스 니펫에 표시된대로 새 함수를 만들고 실행합니다.
이 질문 에서 더 잘 설명했습니다 .
<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>