Hãy tưởng tượng kịch bản này:
Bạn đang xây dựng danh sách người dùng. Bạn đang hiển thị tên, màu sắc yêu thích và email của họ. Khi bạn bấm vào một người dùng (một hàng trong bảng), bạn muốn nó đưa bạn đến bản ghi người dùng. Ngoại trừ khi bạn nhấp vào email, thì hộp thoại email sẽ bật lên.
Bạn có thể viết một số mã như thế này (chúng tôi đang sử dụng một bảng ở đây vì nó dễ hiểu — mặc dù tất nhiên chúng tôi có thể sử dụng một cái gì đó phức tạp hơn nhiều trong dự án của mình):
<Table>
<thead>
<tr>
<th>Name</th>
<th>Colors</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>Susie</td>
<td>Blue, Red</td>
<td>[email protected]</td>
</tr>
</tbody>
</Table>
Nếu bạn muốn nhấp vào một trong những hàng đó, bạn có thể thêm một onClick
chức năng cho hàng. Theo cách đó, nếu họ nhấp vào bất kỳ đâu trong hàng, họ có thể chuyển thẳng đến bản ghi người dùng.

Để xử lý email, chúng tôi sẽ thực hiện một <a hr
ef> trên văn bản.
Nhưng đợi đã! Hộp thoại email bật lên, nhưng chúng tôi cũng điều hướng đến hồ sơ người dùng. Đó không phải là những gì chúng tôi muốn! Làm thế nào để chúng tôi xử lý này? Nhập tuyên truyền sự kiện.
Tuyên truyền sự kiện một cách ngắn gọn.
Sự lan truyền sự kiện là một cách để mô tả “ngăn xếp” các sự kiện được kích hoạt trong trình duyệt web. Trong ví dụ về bảng của chúng tôi ở trên, nhấp vào a
thẻ là sự kiện đầu tiên mà chúng tôi sẽ kích hoạt, nhưng cũng có những sự kiện khác.
Để hiểu khái niệm đó, bạn phải hiểu rằng các phần tử trên trình duyệt web được lồng vào nhau. Họ không bao che cho nhau. Vì vậy, một cú nhấp chuột vào a
thẻ cũng nhấp vào hàng, bảng, div
trong đó bảng được lồng vào nhau và bất kỳ thứ gì khác cho đến hết document
vùng chứa hoàn chỉnh chứa mọi thứ trong trình duyệt của bạn.
Nếu chúng ta đã đặt bất kỳ khác onClick
các sự kiện bên trong các phần tử khác này, chúng cũng sẽ được kích hoạt khi chúng ta nhấp vào a
liên kết trong bảng. Đó là lý do tại sao chúng tôi sẽ được chuyển hướng đến hồ sơ người dùng khi chúng tôi nhấp vào liên kết email. Nó sẽ thực hiện cả hai onClick
chức năng cho a
liên kết và onClick
chức năng cho hàng.
bong bóng
Chuyển động của các sự kiện “lên” từ phần tử được lồng nhiều nhất ( a
) ra ít lồng nhau nhất ( document
) được gọi là “sủi bọt.” Nếu các sự kiện bắt đầu ở phần tử “ngoài cùng nhất” và di chuyển “xuống dưới”, điều đó được gọi là “nhỏ giọt”. Tất cả những gì bạn có thể quan tâm là hành vi mặc định: sủi bọt.
Cách sử dụng lan truyền sự kiện để tạo lợi thế cho bạn
Thành thật mà nói, tôi đã không chạy vào không tí nào trường hợp sử dụng để quan tâm đến việc truyền bá sự kiện cho đến tuần này, khi tôi cần tạo một bảng có hộp kiểm trong đó. Thật không may cho tôi, khi tôi cố gắng thiết lập chức năng kiểm tra, nó đã đưa tôi đến bản ghi. May mắn thay, tôi đã thực hiện một số khóa đào tạo trước đó (xem tài liệu tham khảo bên dưới) đã cho tôi manh mối về chính xác những gì tôi có trên Google.
Bạn có thể đã biết rằng khi bạn tạo một onClick
sự kiện, nó sẽ được chuyển đến bất kỳ chức năng nào bạn gọi.
Vì vậy, ở đây, tôi đã có thể viết:
handleCheck = e => {
e.stopPropagation()
// talk to my API, set the record as "done" or not
}
<span onClick={this.handleCheck}>[]</span>
Điều đó e.stopPropagation()
tạm dừng “sủi bọt” này của các sự kiện “lên” thông qua DOM. Chúng tôi dừng tất cả các sự kiện khác trong ngăn xếp. Thật tuyệt vời!
Vì vậy, toàn bộ hàng của tôi sẽ hoạt động như bình thường và hộp kiểm nhỏ này có thể có một chức năng đặc biệt.
preventDefault
so với stopPropagation
Bạn có thể nghĩ: tại sao không chỉ sử dụng e.preventDefault()
? Đó thực sự là điều đầu tiên tôi đã thử, nhưng đơn giản là không có hành vi mặc định nào cho một khoảng (không giống như biểu mẫu, hành vi gửi mặc định của nó sẽ làm mới trang).
Ví dụ cắt và dán
Tôi viết rất nhiều về React, vì vậy tôi sẽ đưa ra một ví dụ trong React. Nhưng điều này sẽ hoạt động tương tự trong HTML và JavaScript cũ đơn giản, sử dụng bất kỳ phương pháp nào bạn có để thêm trình xử lý sự kiện:
<div onClick={() => console.log('outer div')}>
<div onClick={() => console.log('middle div')}>
<div onClick={() => console.log('innermost div')}>
Click me!
</div>
</div>
</div>
Tuyên truyền sự kiện: bong bóng không có rượu sâm panh.

Người giới thiệu
- Xin cảm ơn Wes Bos, người đầu tiên giới thiệu cho tôi khái niệm này trong khóa học #Javascript30 của anh ấy. Tôi sẽ không biết phải làm gì với Google khi gặp vấn đề được xác định trong bảng ví dụ ở trên nếu tôi không nhìn thấy nó lần đầu trong suốt khóa học.
- Câu trả lời Stack Overflow này, tổng hợp một cách độc đáo một số bit sắc thái hơn của việc nắm bắt và lan truyền sự kiện.