Bài kiểm tra nhanh: mục đích của tham số thứ ba được truyền đến addEventListener()
là gì?
Đừng xấu hổ nếu bạn nghĩ rằng addEventListener()
chỉ lấy hai tham số hoặc có thể chỉ luôn mã hoá cứng giá trị của false
, với một hiểu biết mơ hồ rằng giá trị này có liên quan đến... bong bóng?
addEventListener() có thể định cấu hình hơn
Phương thức addEventListener()
đã đi một chặng đường dài kể từ những ngày đầu của web và chức năng mới của phương thức này được định cấu hình thông qua phiên bản tăng cường của tham số thứ ba đó. Những thay đổi gần đây đối với định nghĩa của phương thức cho phép nhà phát triển cung cấp các tuỳ chọn bổ sung thông qua đối tượng cấu hình, đồng thời vẫn tương thích ngược khi có tham số boolean hoặc khi không chỉ định tuỳ chọn.
Chúng tôi rất vui mừng được thông báo rằng Chrome 55 sẽ hỗ trợ thêm tuỳ chọn once
trong đối tượng cấu hình đó, cùng với các tuỳ chọn passive
(được triển khai trong Chrome 51) và capture
(được triển khai trong Chrome 49). Ví dụ:
element.addEventListener('click', myClickHandler, {
once: true,
passive: true,
capture: true
});
Bạn có thể kết hợp các tuỳ chọn đó cho phù hợp với trường hợp sử dụng của riêng mình.
Lợi ích của việc dọn dẹp sau khi sử dụng
Đó là cú pháp để sử dụng tuỳ chọn once
mới, nhưng bạn sẽ nhận được gì từ đó? Tóm lại, lớp này cung cấp cho bạn một trình nghe sự kiện được điều chỉnh cho các trường hợp sử dụng "một lần và xong".
Theo mặc định, trình nghe sự kiện vẫn tồn tại sau lần đầu tiên được gọi. Đây là điều bạn muốn cho một số loại sự kiện, chẳng hạn như các nút có thể được nhấp nhiều lần. Tuy nhiên, đối với các mục đích sử dụng khác, bạn không cần phải giữ lại trình nghe sự kiện và điều này có thể dẫn đến hành vi không mong muốn nếu bạn có lệnh gọi lại chỉ được thực thi một lần. Các nhà phát triển gọn gàng luôn có thể sử dụng removeEventListener()
để dọn dẹp mọi thứ một cách rõ ràng, theo các mẫu như:
element.addEventListener('click', function cb(event) {
// ...one-time handling of the click event...
event.currentTarget.removeEventListener(event.type, cb);
});
Mã tương đương, sử dụng tham số once
mới, rõ ràng hơn và không buộc bạn phải theo dõi tên của sự kiện (event.type
, trong ví dụ trước) hoặc tham chiếu đến hàm gọi lại (cb
):
element.addEventListener('click', function(event) {
// ...one-time handling of the click event...
}, {once: true});
Việc dọn dẹp trình xử lý sự kiện cũng có thể mang lại hiệu quả sử dụng bộ nhớ bằng cách huỷ bỏ phạm vi liên kết với hàm gọi lại, cho phép thu thập rác bất kỳ biến nào được ghi lại trong phạm vi đó. Dưới đây là một ví dụ về trường hợp như vậy:
function setUpListeners() {
var data = ['one', 'two', '...etc.'];
window.addEventListener('load', function() {
doSomethingWithSomeData(data);
// data is now part of the callback's scope.
});
}
Theo mặc định, lệnh gọi lại trình nghe sự kiện load
sẽ vẫn nằm trong phạm vi khi hoàn tất quá trình chạy, mặc dù lệnh gọi lại này không bao giờ được sử dụng lại. Vì biến data
được sử dụng bên trong lệnh gọi lại, nên biến này cũng sẽ vẫn nằm trong phạm vi và không bao giờ được thu thập rác. Tuy nhiên, nếu lệnh gọi lại bị xoá thông qua tham số once
, thì cả hàm và mọi thứ được duy trì thông qua phạm vi của hàm đó đều có thể là ứng cử viên để thu gom rác.
Hỗ trợ trình duyệt
Chrome 55 trở lên, Firefox 50 trở lên và bản dùng thử công nghệ 7 trở lên của Safari có hỗ trợ gốc cho tuỳ chọn once
.
Nhiều thư viện giao diện người dùng JavaScript cung cấp các phương thức thuận tiện để tạo trình nghe sự kiện và một số thư viện có lối tắt để xác định sự kiện một lần, đáng chú ý nhất là phương thức one()
của jQuery. Bạn cũng có thể sử dụng một polyfill trong thư viện dom4
của Andrea Giammarchi.
Cảm ơn bạn!
Cảm ơn Ingvar Stepanyan đã đưa ra ý kiến phản hồi về mã mẫu trong bài đăng này.