Làm cách nào để thêm trình nghe sự kiện riêng lẻ bằng cách sử dụng jquery .each ()?
Tôi có một thiết lập đơn giản: Hai nút với các giá trị khác nhau. Tôi muốn sử dụng hàm .each () từ jquery để thêm trình xử lý sự kiện nhấp chuột vào mỗi nút chỉ ghi lại các giá trị của mỗi nút. Nhưng bằng cách nào đó khi sử dụng .each (), jquery sẽ ghi đè trình xử lý nhấp chuột cho (các) nút trước đó. Điều này khiến tôi có hai câu hỏi:
- Tại sao vậy?
- Làm cách nào để thêm trình nghe sự kiện riêng lẻ vào tập hợp các đối tượng jquery?
Xem mã bên dưới
<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>
Trả lời
Vấn đề trong mã của bạn là do bạn đã khai báo ngầm các biến type
và value
, vì vậy chúng nằm trong window
phạm vi. Như vậy, mỗi lần lặp sau sẽ ghi đè các giá trị để chỉ các giá trị cuối cùng được nhìn thấy sau khi vòng lặp kết thúc.
Để khắc phục điều này, hãy xác định các biến trong vòng lặp:
$(() => { $(`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>
Tuy nhiên , bạn không cầneach()
vòng lặp. Bạn có thể khắc phục sự cố và cải thiện chất lượng mã bằng cách liên kết cùng một trình xử lý sự kiện với tất cả cácbutton
phần tử và sử dụng thuộctarget
tính của sự kiện được nâng lên để truy cập các thuộc tính của chúng.
Ngoài ra, hãy lưu ý rằng việc thêm các thuộc tính không chuẩn của riêng bạn, toggle
trong trường hợp này, có thể dẫn đến các vấn đề trong giao diện người dùng và JS. Một cách tiếp cận tốt hơn là sử dụng một lớp để nhóm các phần tử.
Cuối cùng, one
và two
không phải là giá trị hợp lệ cho type
thuộc tính. data
Thay vào đó, hãy sử dụng một thuộc tính để đính kèm siêu dữ liệu tùy chỉnh của riêng bạn vào một phần tử.
Với tất cả những gì đã nói, hãy thử điều này:
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>
sử dụng $(this)
bên trong lệnh gọi lại nhấp chuột
$(() => {
$(`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>
Và cũng không cần phải đề cập đến bên trong mỗi cuộc gọi lại. Bạn có thể gọi theo cách bình thường như bên dưới
$(() => { $(`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>
- Bởi vì người nghe liên kết với giá trị cuối cùng của $ toggle.
- Bằng cách tạo và chạy một chức năng mới như được hiển thị trong đoạn mã.
Giải thích tốt hơn trong câu hỏi này .
<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>