Cuối cùng cái sai là gì? Cảm ơn.
window.addEventListener('load', function() {
alert("All done");
}, false);
Cuối cùng cái sai là gì? Cảm ơn.
window.addEventListener('load', function() {
alert("All done");
}, false);
Câu trả lời:
Theo MDN Web Docs , tham số thứ ba là:
useCapture
Iftrue,useCapturecho biết rằng người dùng muốn bắt đầu chụp. Sau khi bắt đầu nắm bắt, tất cả các sự kiện thuộc loại được chỉ định sẽ được gửi đến người đã đăng kýlistenertrước khi được gửi đến bất kỳ sự kiện nàoEventTargetbên dưới nó trong cây DOM. Các sự kiện đang sôi sục lên qua cây sẽ không kích hoạt người nghe được chỉ định sử dụng tính năng chụp. Xem Sự kiện DOM cấp 3 để có giải thích chi tiết.
Tôi cũng đã kiểm tra MDN, nhưng tôi vẫn không hiểu nó useCapturedùng để làm gì, vì vậy câu trả lời này dành cho những ai vẫn chưa hiểu sau khi đã kiểm tra tài liệu chính thức.
Vì vậy, trước hết, những điều sau đây xảy ra ở hầu hết mọi người:
Trong tất cả các trình duyệt, ngoại trừ IE <9, có hai giai đoạn xử lý sự kiện.
Sự kiện đầu tiên đi xuống - được gọi là bắt , và sau đó bong bóng lên . Hành vi này được độc lập hóa trong đặc tả W3C.
có nghĩa là bất kể bạn đặt thành useCapturegì, hai giai đoạn sự kiện này luôn tồn tại.
Hình ảnh này cho thấy nó hoạt động như thế nào.

Theo mô hình này, sự kiện:
Chụp xuống - đến 1 -> 2 -> 3.
Bong bóng lên - đến 3 -> 2 -> 1.
Sau đó đến câu hỏi của bạn. Tham số thứ 3 được gọi useCapturecho biết bạn muốn trình xử lý của mình xử lý sự kiện nào trong hai giai đoạn.
useCapture = trueTrình xử lý được thiết lập ở giai đoạn bắt. Các sự kiện sẽ đến với nó trước khi đến với con cái của nó.
useCapture = false.Bộ xử lý được đặt ở giai đoạn sủi bọt. Các sự kiện sẽ đến với nó sau khi đến với con cái của nó.
có nghĩa là nếu bạn viết mã như thế này:
child.addEventListener("click", second);
parent.addEventListener("click", first, true);
khi nhấp vào phần tử con, firstphương thức sẽ được gọi trước đó second.
Theo mặc định, useCapturecờ được đặt thành false , có nghĩa là trình xử lý của bạn sẽ chỉ được gọi trong giai đoạn tạo bọt sự kiện .
Để biết thông tin chi tiết, hãy nhấp vào liên kết tham khảo này và điều này .
Câu trả lời của @ Libra rất hay, tình cờ có một số người như tôi hiểu rõ hơn sự tương tác của đoạn mã với máy.
Vì vậy, kịch bản sau đây sẽ giải thích sự lan truyền sự kiện. Những gì tôi đang cố gắng thực hiện dựa trên giản đồ mô tả này là:
Theo dòng sự kiện đi xuống và lên trên hệ thống phân cấp sau:
<window>
<document>
<body>
<section>
<div>
<paragraph>
<span>
Để đơn giản hơn, chúng ta sẽ bắt đầu từ phần thân xuống các trình xử lý đăng ký phần tử span cho giai đoạn bắt và sao lưu vào các trình xử lý đăng ký phần tử thân cho giai đoạn sủi bọt. Vì vậy, kết quả sẽ là từng nút theo hướng của sự kiện từ đầu đến cuối. Vui lòng nhấp vào "Hiển thị bảng điều khiển" trên bảng điều khiển bên phải của đoạn mã để truy cập nhật ký
function handler(e){
/* logs messages of each phase of the event flow associated with
the actual node where the flow was passing by */
if ( e.eventPhase == Event.CAPTURING_PHASE ){
console.log ("capturing phase :\n actual node : "+this.nodeName);
}
if ( e.eventPhase == Event.AT_TARGET){
console.log( "at target phase :\n actual node : "+this.nodeName);
}
if ( e.eventPhase == Event.BUBBLING_PHASE){
console.log ("bubbling phase :\n actual node : "+this.nodeName );
}
}
/* The following array contains the elements between the target (span and you can
click also on the paragraph) and its ancestors up to the BODY element, it can still
go up to the "document" then the "window" element, for the sake of simplicity it is
chosen to stop here at the body element
*/
arr=[document.body,document.getElementById("sectionID"),
document.getElementById("DivId"),document.getElementById("PId"),
document.getElementById("spanId")];
/* Then trying to register handelers for both capturing and bubbling phases
*/
function listener(node){
node.addEventListener( ev, handler, bool )
/* ev :event (click), handler : logging the event associated with
the target, bool: capturing/bubbling phase */
}
ev="click";
bool=true; // Capturing phase
arr.forEach(listener);
bool=false; // Bubbling phase
/* Notice that both capturing and bubbling
include the at_target phase, that's why you'll get two `at_target` phases in
the log */
arr.forEach(listener);
p {
background: gray;
color:white;
padding: 10px;
margin: 5px;
border: thin solid black
}
span {
background: white;
color: black;
padding: 2px;
cursor: default;
}
<section ID="sectionID">
<div id="DivId">
<p id="PId">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis <span id="spanId">CLICK ME </span> imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq.
</p>
</div>
</section>
Lưu ý rằng các sự kiện như tiêu điểm không bong bóng, điều này làm cho cảm giác vẫn còn phần lớn các sự kiện có bong bóng.