Tôi muốn thêm một số nhận xét và phản biện vào câu trả lời của jfriend00. (chủ yếu chỉ là ý kiến của tôi dựa trên cảm giác ruột của tôi)
Không - bạn KHÔNG nên ràng buộc tất cả các trình xử lý sự kiện được ủy quyền vào đối tượng tài liệu. Đó có lẽ là kịch bản thực hiện tồi tệ nhất bạn có thể tạo ra.
Trước hết, ủy nhiệm sự kiện không phải lúc nào cũng làm cho mã của bạn nhanh hơn. Trong một số trường hợp, đó là lợi thế và trong một số trường hợp thì không. Bạn nên sử dụng ủy quyền sự kiện khi bạn thực sự cần ủy quyền sự kiện và khi bạn được hưởng lợi từ nó. Mặt khác, bạn nên liên kết các trình xử lý sự kiện trực tiếp với các đối tượng nơi sự kiện xảy ra vì điều này thường sẽ hiệu quả hơn.
Mặc dù sự thật là hiệu suất có thể tốt hơn một chút nếu bạn chỉ đăng ký và tổ chức sự kiện cho một yếu tố duy nhất, tôi tin rằng nó không cân nhắc với lợi ích về khả năng mở rộng mà phái đoàn mang lại. Tôi cũng tin rằng các trình duyệt đang (sẽ) xử lý việc này ngày càng hiệu quả hơn, mặc dù tôi không có bằng chứng nào về việc này. Theo tôi, đoàn sự kiện là con đường để đi!
Thứ hai, bạn KHÔNG nên ràng buộc tất cả các sự kiện được ủy quyền ở cấp độ tài liệu. Đây chính xác là lý do tại sao .live () không được dùng nữa vì điều này rất không hiệu quả khi bạn có rất nhiều sự kiện bị ràng buộc theo cách này. Đối với việc xử lý sự kiện được ủy nhiệm, RẤT NHIỀU để ràng buộc chúng với cha mẹ gần nhất không động.
Tôi đồng ý về điều này. Nếu bạn chắc chắn 100% rằng một sự kiện sẽ chỉ xảy ra bên trong một container, sẽ rất hợp lý khi liên kết sự kiện với container này, nhưng tôi vẫn sẽ tranh luận trực tiếp với các sự kiện ràng buộc với yếu tố kích hoạt.
Thứ ba, không phải tất cả các sự kiện hoạt động hoặc tất cả các vấn đề có thể được giải quyết với ủy quyền. Ví dụ: nếu bạn muốn chặn các sự kiện chính trên điều khiển đầu vào và chặn các khóa không hợp lệ được nhập vào điều khiển đầu vào, bạn không thể làm điều đó với việc xử lý sự kiện được ủy quyền bởi vì khi sự kiện nổi lên với trình xử lý được ủy quyền, thì nó đã đã được xử lý bởi điều khiển đầu vào và đã quá muộn để ảnh hưởng đến hành vi đó.
Đơn giản là nó sai. Vui lòng xem mã nàyPen: https://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
Nó minh họa cách bạn có thể ngăn người dùng gõ bằng cách đăng ký sự kiện nhấn phím trên tài liệu.
Dưới đây là những thời điểm mà sự kiện được yêu cầu hoặc thuận lợi:
Khi các đối tượng bạn đang chụp các sự kiện trên được tạo / xóa động và bạn vẫn muốn ghi lại các sự kiện trên chúng mà không cần phải xử lý lại rõ ràng các trình xử lý sự kiện mỗi khi bạn tạo một sự kiện mới. Khi bạn có rất nhiều đối tượng mà tất cả đều muốn cùng một trình xử lý sự kiện (trong đó số lượng ít nhất là hàng trăm). Trong trường hợp này, có thể hiệu quả hơn tại thời điểm thiết lập để liên kết một trình xử lý sự kiện được ủy quyền thay vì hàng trăm hoặc nhiều trình xử lý sự kiện trực tiếp. Lưu ý, xử lý sự kiện được ủy nhiệm luôn kém hiệu quả hơn trong thời gian chạy so với xử lý sự kiện trực tiếp.
Tôi muốn trả lời với trích dẫn này từ https://ehsangazar.com/optimizing-javascript-event-listpers-for-performance-e28406ad406c
Event delegation promotes binding as few DOM event handlers as possible, since each event handler requires memory. For example, let’s say that we have an HTML unordered list we want to bind event handlers to. Instead of binding a click event handler for each list item (which may be hundreds for all we know), we bind one click handler to the parent unordered list itself.
Ngoài ra, googling cho performance cost of event delegation google
trả lại nhiều kết quả có lợi cho phái đoàn sự kiện.
Khi bạn đang cố gắng nắm bắt (ở mức cao hơn trong tài liệu của mình) các sự kiện xảy ra trên bất kỳ yếu tố nào trong tài liệu. Khi thiết kế của bạn rõ ràng bằng cách sử dụng bong bóng sự kiện và stopPropagation () để giải quyết một số vấn đề hoặc tính năng trong trang của bạn. Để hiểu điều này nhiều hơn một chút, người ta cần hiểu cách các trình xử lý sự kiện được ủy quyền của jQuery hoạt động. Khi bạn gọi một cái gì đó như thế này:
$ ("# myParent"). on ('click', 'button.actionButton', myFn); Nó cài đặt một trình xử lý sự kiện jQuery chung trên đối tượng #myParent. Khi một sự kiện nhấp vào bong bóng đến trình xử lý sự kiện được ủy quyền này, jQuery phải xem qua danh sách các trình xử lý sự kiện được ủy quyền gắn với đối tượng này và xem liệu phần tử khởi tạo cho sự kiện có khớp với bất kỳ bộ chọn nào trong các trình xử lý sự kiện được ủy nhiệm không.
Do các bộ chọn có thể tham gia khá nhiều, điều này có nghĩa là jQuery phải phân tích từng bộ chọn và sau đó so sánh nó với các đặc điểm của mục tiêu sự kiện ban đầu để xem nó có khớp với từng bộ chọn không. Đây không phải là một hoạt động giá rẻ. Sẽ không có vấn đề gì lớn nếu chỉ có một trong số họ, nhưng nếu bạn đặt tất cả các công cụ chọn của mình vào đối tượng tài liệu và có hàng trăm công cụ chọn để so sánh với mọi sự kiện bị bong bóng, điều này có thể nghiêm túc bắt đầu xử lý hiệu suất xử lý sự kiện.
Vì lý do này, bạn muốn thiết lập trình xử lý sự kiện được ủy quyền của mình để trình xử lý sự kiện được ủy nhiệm càng gần đối tượng mục tiêu càng thiết thực. Điều này có nghĩa là ít sự kiện sẽ bong bóng qua mỗi bộ xử lý sự kiện được ủy quyền, do đó cải thiện hiệu suất. Đặt tất cả các sự kiện được ủy nhiệm vào đối tượng tài liệu là hiệu suất tồi tệ nhất có thể vì tất cả các sự kiện bị bong bóng phải trải qua tất cả các trình xử lý sự kiện được ủy quyền và được đánh giá theo tất cả các bộ chọn sự kiện được ủy quyền có thể. Đây chính xác là lý do tại sao .live () bị phản đối vì đây là những gì .live () đã làm và nó tỏ ra rất kém hiệu quả.
Tài liệu này ở đâu? Nếu đó là sự thật, thì jQuery dường như đang xử lý ủy quyền theo cách rất kém hiệu quả, và sau đó các đối số phản biện của tôi chỉ nên được áp dụng cho vanilla JS.
Tuy nhiên: Tôi muốn tìm một nguồn chính thức hỗ trợ cho yêu cầu này.
:: BIÊN TẬP ::
Có vẻ như jQuery thực sự đang thực hiện bong bóng sự kiện theo cách rất kém hiệu quả (vì họ hỗ trợ IE8)
https://api.jquery.com/on/#event-performance
Vì vậy, hầu hết các lập luận của tôi ở đây chỉ đúng với vanilla JS và các trình duyệt hiện đại.