2015-04-11 17 views
5

Tôi có một phụ huynh <div> với một đứa trẻ <div> trong bộ nhớ - không được đính kèm với tài liệu hiện tại. Tôi muốn kích hoạt một số CustomEvent trên đứa trẻ nhưng lắng nghe sự kiện đó từ cha mẹ. Đây là mã của tôi:Tại sao sự kiện bubbling không hoạt động trong các phần tử DOM tách rời?

var parent = document.createElement('div'); 
var child = document.createElement('div'); 
parent.appendChild(child); 
parent.addEventListener('boom', function(event) { 
    console.log('parent listener', event); // <~ This never runs! 
}); 
var event = new CustomEvent('boom', { bubbles: true }); 
child.dispatchEvent(event); 

Mã này không hoạt động như mong đợi. Trình nghe sự kiện trên phụ huynh không bao giờ kích hoạt. Điều này có vẻ là một mâu thuẫn với hệ thống sự kiện JavaScript, theo đó các sự kiện phát sinh từ mục tiêu. Tuy nhiên, nếu tôi sửa đổi hai dòng cuối cùng của đoạn này để sau, đám cháy callback như tôi mong chờ nó:

document.body.appendChild(parent); 
child.dispatchEvent(event); 

Nói cách khác, nếu tôi gắn mảnh của tôi như là một cây con của tài liệu trước khi cử sự kiện, sau đó trình nghe sự kiện cha mẹ kích hoạt chính xác như mong đợi. Tại sao? Có cách nào để cho phép sủi bọt khi sử dụng các phần tử DOM tách rời không?

+1

Tôi không thấy bất kỳ DOM ảo nào ở đây, DOM ảo thường có nghĩa là DOM không thực sự DOM - DOM của bạn ở đây rất thực tế, chỉ cần tách ra. –

+0

Ngoài ra, đây là giải pháp https://medium.com/@webprolific/bubbling-events-in-detached-dom-trees-35c34b551723, nếu điều này giải quyết được vấn đề cho bạn, vui lòng viết câu trả lời cho khách truy cập trong tương lai :) –

+0

@RobG đó là mô hình đối tượng tài liệu, nó thể hiện cách bạn tương tác với các tài liệu thông qua một API đối tượng, một phần tử với một đứa trẻ chắc chắn là một đối tượng chỉ định tương tác với tài liệu và tài liệu không chỉ là cây dom. AJAX và như vậy cũng là một phần của API DOM và do đó là các webworker. –

Trả lời

4

Tại sao [không sủi bọt hoạt động trên các phần tử tách rời]?

Để trả lời câu hỏi đầu tiên của bạn, tôi đã xem W3C "UI Events (formerly DOM Level 3 Events)" spec và không thấy bất kỳ điều gì giải quyết vấn đề này một cách cụ thể. Tuy nhiên, phần event phase đề cập đến một vài điều khiến hành vi này có vẻ hợp lý.

Khi bước tiếp theo, đối tượng sự kiện phải hoàn thành một hoặc nhiều giai đoạn sự kiện. Đặc điểm kỹ thuật này xác định ba pha sự kiện: pha chụp, pha đích và pha bong bóng. Đối tượng sự kiện hoàn thành các giai đoạn này theo thứ tự được chỉ định bằng cách sử dụng các đường dẫn truyền một phần như được định nghĩa bên dưới. Một pha phải được bỏ qua nếu nó không được hỗ trợ, hoặc nếu tuyên truyền của đối tượng sự kiện đã bị dừng. Ví dụ: nếu thuộc tính Event.bubbles được đặt thành false, pha bong bóng sẽ bị bỏ qua và nếu Event.stopPropagation() đã được gọi trước khi công văn, tất cả các giai đoạn phải được bỏ qua.

Mỏ nhấn mạnh.

Các spec sau đó tiếp tục liệt kê các giai đoạn:

  1. Các chụp giai đoạn: Các đối tượng sự kiện phải tuyên truyền thông qua các tổ tiên của mục tiêu từ cửa sổ để cha mẹ của mục tiêu. Giai đoạn này còn được gọi là giai đoạn bắt giữ. Người nghe sự kiện đã đăng ký cho giai đoạn này phải xử lý sự kiện trước khi nó đạt được mục tiêu của nó.
  2. pha đích: Đối tượng sự kiện phải đến mục tiêu sự kiện của đối tượng sự kiện. Giai đoạn này còn được gọi là giai đoạn tại mục tiêu. Trình lắng nghe sự kiện đã đăng ký cho giai đoạn này phải xử lý sự kiện khi nó đã đạt được mục tiêu của nó. Nếu loại sự kiện cho biết rằng sự kiện không được bong bóng, đối tượng sự kiện phải tạm dừng sau khi hoàn thành giai đoạn này.
  3. Giai đoạn bong bóng : Đối tượng sự kiện truyền qua tổ tiên của mục tiêu theo thứ tự ngược lại, bắt đầu với cha mẹ của mục tiêu và kết thúc bằng Cửa sổ. Giai đoạn này còn được gọi là pha bọt. Người nghe sự kiện đã đăng ký cho giai đoạn này phải xử lý sự kiện sau khi nó đã đạt được mục tiêu của nó.

Một lần nữa, nhấn mạnh mỏ. Thông số kỹ thuật không bao giờ gọi ra những gì xảy ra với các phần tử tách rời một cách rõ ràng. Do các pha mục tiêu và bong bóng yêu cầu đường dẫn đi từ phần tử đến cửa sổ và không có đường dẫn nào có thể trên các phần tử tách rời, nó sẽ theo sau các pha sự kiện mục tiêu và bong bóng phải bỏ qua vì các đường dẫn đó không được hỗ trợ.

Có cách nào để cho phép bong bóng khi sử dụng các phần tử DOM tách rời không?

Theo như tôi có thể biết, không có gì tích hợp sẽ cho phép sủi bọt. Bạn có thể có khả năng tạo bọt giả với một số mã tùy chỉnh, nhưng điều đó sẽ yêu cầu kiểm tra xem phần tử có bị tách ra mỗi khi bạn kích hoạt một sự kiện hay không.

Một suy nghĩ khác là thêm các phần tử vào DOM, kích hoạt sự kiện và tách các phần tử. Vì tôi chưa thử nghiệm điều này, tôi không biết liệu nó có hiệu quả hay không.

+0

Tôi đoán là cụm từ chỉ ở đó để làm cho tương thích với IE không hỗ trợ giai đoạn chụp. – Bergi

+0

Đây là một câu trả lời tuyệt vời và tôi đồng ý rằng mặc dù thông số không rõ ràng về hành vi trong tình huống này, Trong mọi trường hợp, việc thực hiện sự kiện bubbling "thủ công" đủ đơn giản: chỉ cần gửi đối tượng sự kiện tới mọi 'parentNode', bắt đầu từ đích mong muốn d đi ngang qua đỉnh của cây bị tách rời. – GladstoneKeep

+0

@GladstoneKeep, có vẻ như đủ dễ dàng, nhưng bạn vẫn phải nhớ gán đúng thuộc tính 'target' và' currentTarget' cho sự kiện. Đối với tôi nó có vẻ như rất nhiều chi phí để hỗ trợ. – zzzzBov

Các vấn đề liên quan