Sau khi mở trình nghe sự kiện

Jeff Posnick
J Jeff Posnick

Câu đố bật lên: 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 một giá trị false, với sự hiểu nhầm rằng nó có liên quan đến... bong bóng?

addEventListener() có thể định cấu hình cao hơn

Phương thức addEventListener() đã phát triển vượt bậc 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 về định nghĩa của phương thức cho phép nhà phát triển cung cấp thêm các tuỳ chọn thông qua một đối tượng cấu hình, trong khi vẫn tương thích ngược khi có thông số boolean hoặc khi một tuỳ chọn không được chỉ định.

Chúng tôi vui mừng thông báo rằng Chrome 55 bổ sung tính năng hỗ trợ cho 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 và kết hợp những lựa chọn đó sao 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 ngủ

Đó là cú pháp để sử dụng tuỳ chọn once mới, nhưng điều đó giúp bạn làm gì? Tóm lại, công cụ này cung cấp cho bạn một trình nghe sự kiện được điều chỉnh cho phù hợp với các trường hợp sử dụng "một và xong".

Theo mặc định, trình nghe sự kiện vẫn tồn tại sau lần đầu tiên chúng được gọi. Đây là điều bạn muốn đối với 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 trường hợp sử dụng khác, việc sử dụng trình nghe sự kiện là không cần thiết và có thể dẫn đến hành vi không mong muốn nếu bạn có một lệnh gọi lại chỉ phải thực thi một lần. Nhà phát triển thiết bị vệ sinh luôn có thể sử dụng removeEventListener() để dọn dẹp rõ ràng mọi thứ, 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 khi sử dụng tham số once mới sẽ gọn gà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 callback (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

Việc dọn dẹp các trình xử lý sự kiện cũng có thể mang lại hiệu quả cho bộ nhớ bằng cách huỷ bỏ phạm vi liên kết với hàm callback, cho phép thu gom rác bất kỳ biến nào được thu thập trong phạm vi đó. Dưới đây là một ví dụ về sự khác biệt:

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 chạy xong, mặc dù không bao giờ được sử dụng lại. Vì biến data được dùng bên trong lệnh gọi lại, nên biến này cũng sẽ 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ả chính hàm đó và mọi nội dung được duy trì qua phạm vi của hàm gọi lại đều có thể là ứng viên để thu thập rác.

Hỗ trợ trình duyệt

Chrome 55 trở lên, Firefox 50 trở lên và bản xem trước công nghệ 7+ của Safari 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 tiện lợi để 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. Tính năng polyfill cũng được cung cấp như một phần trong thư viện dom4 của Andrea Giammarchi.

Cảm ơn bạn!

Cảm ơn Ingvar Stepanyan đã phản hồi về mã mẫu trong bài đăng này.