วิธีเพิ่มผู้ฟังเหตุการณ์แต่ละคนโดยใช้ jquery .each ()?
ฉันมีการตั้งค่าง่ายๆ: ปุ่มสองปุ่มที่มีค่าต่างกัน ฉันต้องการใช้ฟังก์ชัน. each () จาก jquery เพื่อเพิ่มตัวฟังเหตุการณ์การคลิกให้กับแต่ละปุ่มที่บันทึกค่าของแต่ละปุ่ม แต่เมื่อใช้. 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>