Tại sao 'false' được sử dụng sau hàm addEventListener đơn giản này?


91

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:


11

Theo MDN Web Docs , tham số thứ ba là:

useCapture
If true, 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ào EventTargetbê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.


26
Tôi không biết quá nhiều về javascript, vì vậy tôi gặp khó khăn khi tìm câu trả lời này. Tôi thực sự không biết useCapture là gì? Bạn vui lòng cho tôi biết điều gì đó về nó.
Ashoka Mondal

1
@BikashChandraMondal hãy xem câu trả lời bên dưới.
libra

35
Vui lòng giải thích, đừng chỉ sao chép / dán.
Damjan Pavlica

3
Thật là một trò copy-paste vô dụng.
Sebastian Palma

325

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.

nhập mô tả hình ảnh ở đây

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 = true

Trì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điều này .


13
Câu trả lời rất hay và toàn diện. Tôi hiểu nó hơn rất nhiều so với bây giờ.
0x499602D2

15
Giải thích rất tốt. Sự tiếp xúc của con người, đó là điều tạo nên sự khác biệt.
Rafael Eyng

1
Tôi thực sự đánh giá cao lời giải thích này.
neilsimp1

1
Câu trả lời chính xác. Bạn cũng có thể giải thích cách tiếp cận nào nên được sử dụng khi nào?
Rahul Arora

1
Đây phải là câu trả lời đã chọn. OP, bạn có thể vui lòng làm điều đó?
Saurabh Tiwari

6

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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.