Przeczytałem artykuł na https://developer.mozilla.org/en/DOM/element.addEventListener, ale nie mogę zrozumieć useCapture
atrybutu. Definicja to:
Jeśli true, useCapture wskazuje, że użytkownik chce zainicjować przechwytywanie. Po zainicjowaniu przechwytywania wszystkie zdarzenia określonego typu zostaną wysłane do zarejestrowanego odbiornika, zanim zostaną wysłane do dowolnych obiektów EventTargets pod nim w drzewie DOM. Wydarzenia, które bulgoczą w górę przez drzewo, nie wyzwalają słuchacza wyznaczonego do użycia przechwytywania.
W tym kodzie zdarzenie nadrzędne wyzwala się przed dzieckiem, więc nie jestem w stanie zrozumieć jego zachowania. Obiekt dokumentu ma usecapture true, a div div ma usecapture ustawiony na false, a dokument usecapture jest przestrzegany.
function load() {
document.addEventListener("click", function() {
alert("parent event");
}, true);
document.getElementById("div1").addEventListener("click", function() {
alert("child event");
}, false);
}
<body onload="load()">
<div id="div1">click me</div>
</body>
źródło
no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget
. Nie przetestowałem wszystkich przeglądarek, więc mogą się zdarzyć, że zaimplementują to w ten sam sposób. Zdarzenia przechwytywania będą jednak wykonywane przed zdarzeniami nie przechwytywania.Uważam, że ten schemat jest bardzo przydatny do zrozumienia faz przechwytywania / celu / bąbelków: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Event-20031107/events.html#Events-phases
Poniżej treść pobrana z linku.
Fazy
Zdarzenie jest wywoływane zgodnie ze ścieżką od katalogu głównego drzewa do tego węzła docelowego. Następnie można go obsłużyć lokalnie na poziomie węzła docelowego lub od przodków dowolnego celu wyżej w drzewie. Wywoływanie zdarzeń (zwane także propagacją zdarzeń) odbywa się w trzech fazach i w następującej kolejności:
Przodkowie celu są określani przed początkową wysyłką zdarzenia. Jeśli węzeł docelowy zostanie usunięty podczas wysyłki lub dodany lub usunięty zostanie przodek celu, propagacja zdarzeń będzie zawsze oparta na węźle docelowym, a przodkowie celu zostaną ustaleni przed wysyłką.
Niektóre zdarzenia niekoniecznie muszą spełniać trzy fazy przepływu zdarzeń DOM, np. Zdarzenie można zdefiniować tylko dla jednej lub dwóch faz. Na przykład zdarzenia zdefiniowane w tej specyfikacji zawsze osiągną fazę przechwytywania i fazę docelową, ale niektóre nie osiągną fazy propagacji („zdarzenia propagacji” w porównaniu z „zdarzeniami niestabilnymi”, patrz także atrybut Event.bubbles).
źródło
Window
zamiastdocument
, ponieważdocument
jest dzieckiemWindow
?Capture Event (
useCapture = true
) vs Bubble Event (useCapture = false
)Odniesienie MDN
useCapture
parametr nie ma znaczenia (Dzięki @bam i @ legend80s)stopPropagation()
zatrzyma przepływPróbny
Wynik:
Bańka docelowa 1
(Ponieważ Capture i Bubble of Target zostaną uruchomione w kolejności, w jakiej zostały zarejestrowane, więc zdarzenie Bubble zostanie uruchomione przed zdarzeniem Capture)
Przechwytywanie celu
źródło
Events in the target phase will trigger all listeners on an element in the order they were registered, regardless of the useCapture parameter.
From developer.mozilla.org/en-US/docs/Web/API/EventTarget/… . Dlatego nie ma fazy „Przechwytywanie dzieci” i „Bańka dziecięca”.Kiedy powiesz useCapture = true, Zdarzenia wykonują się od góry do dołu w fazie przechwytywania, gdy false, powoduje to bąbelkowanie od dołu do góry.
źródło
Chodzi o modele zdarzeń: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow Możesz wychwycić zdarzenie w fazie propagacji lub przechwytywania. Twój wybór.
Spójrz na http://www.quirksmode.org/js/events_order.html - przekonasz się, że jest to bardzo przydatne.
źródło
Przykład kodu:
Kod JavaScript:
jeśli oba są ustawione na false
Wykonuje: Onclick Wewnętrzny Div, alarmy są wyświetlane jako: Div 2> Div 1
Tutaj skrypt jest wykonywany z elementu wewnętrznego: Event Bubbling (useCapture zostało ustawione na false)
div 1 jest ustawiony na true, a div 2 na false
Wykonuje: Po kliknięciu opcji Wewnętrzna dywizja alerty są wyświetlane jako: Div 1> Div 2
Tutaj skrypt jest wykonywany z elementu nadrzędnego / zewnętrznego: Przechwytywanie zdarzeń (parametr useCapture został ustawiony na wartość true)
div 1 ma wartość false, a div 2 ma wartość true
Wykonuje: Onclick Wewnętrzny Div, alarmy są wyświetlane jako: Div 2> Div 1
Tutaj skrypt jest wykonywany z elementu wewnętrznego: Event Bubbling (useCapture zostało ustawione na false)
div 1 jest ustawiony na true, a div 2 ustawiony na true
Wykonuje: Po kliknięciu opcji Wewnętrzna dywizja alerty są wyświetlane jako: Div 1> Div 2
Tutaj skrypt jest wykonywany z elementu nadrzędnego / zewnętrznego: Przechwytywanie zdarzeń, ponieważ parametr useCapture został ustawiony na wartość true
źródło
Podsumowanie:
DOM
Spec jak opisano w:https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
działa w następujący sposób:
Zdarzenie jest wywoływane po ścieżce od katalogu głównego (
document
) drzewa do węzła docelowego . Węzeł docelowy jest najgłębszymHTML
elementem, tj. Event.target. Wywoływanie zdarzeń (zwane także propagacją zdarzeń) odbywa się w trzech fazach i w następującej kolejności:document
) do bezpośredniego rodzica węzła docelowego.html
elementem, na którym wydarzenie zostało odrzucone.Przykład:
Powyższy przykład naprawdę ilustruje różnicę między propagacją zdarzeń a przechwytywaniem zdarzeń. Podczas dodawania detektorów zdarzeń za pomocą
addEventListener
jest trzeci element o nazwie useCapture. To ustawienie,boolean
które po ustawieniutrue
pozwala odbiornikowi zdarzenia na użycie przechwytywania zdarzeń zamiast propagacji zdarzeń.W naszym przykładzie, gdy ustawiamy argument useCapture na
false
, widzimy, że następuje propagacja zdarzeń. Najpierw uruchamiane jest zdarzenie w fazie docelowej (logi innerBubble), a następnie poprzez bąbelkowanie zdarzenia uruchamiane jest zdarzenie w elemencie nadrzędnym (logi outerBubble).Kiedy ustawimy argument useCapture, aby
true
zobaczyć, że zdarzenie w zewnętrznej pamięci<div>
jest uruchamiane jako pierwsze. Jest tak, ponieważ zdarzenie jest teraz odpalane w fazie przechwytywania, a nie w fazie bulgotania.źródło
Biorąc pod uwagę trzy fazy podróży wydarzenia :
useCapture
wskazuje, na których fazach będzie odbywać się podróż zdarzenia :Źródło jest takie samo jak druga najlepsza odpowiedź: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Event-20031107/events.html#Events-phases
źródło
Kolejność definicji ma znaczenie tylko wtedy, gdy elementy są na tym samym poziomie. Jeśli odwrócisz kolejność definicji w kodzie, otrzymasz takie same wyniki.
Jeśli jednak odwrócisz ustawienie useCapture na dwóch modułach obsługi zdarzeń, moduł obsługi zdarzeń podrzędnych zareaguje przed ustawieniem elementu nadrzędnego. Powodem tego jest to, że procedura obsługi zdarzeń potomnych będzie teraz wyzwalana w fazie przechwytywania, która jest przed fazą propagacji, w której wyzwalana jest procedura obsługi zdarzeń nadrzędnych.
Jeśli ustawisz wartość useCapture na wartość true dla obu procedur obsługi zdarzeń - niezależnie od kolejności definicji - funkcja obsługi zdarzeń nadrzędnych zostanie uruchomiona jako pierwsza, ponieważ występuje ona przed dzieckiem w fazie przechwytywania.
I odwrotnie, jeśli ustawisz useCapture na false dla obu procedur obsługi zdarzeń - ponownie bez względu na kolejność definicji - procedura obsługi zdarzeń podrzędnych zostanie uruchomiona jako pierwsza, ponieważ jest ona nadrzędna w fazie propagacji.
źródło