Не в состоянии понять параметр usecapture в метод addEventListener
Я прочитал статью в https://developer.mozilla.org/en/DOM/element.addEventListener но не в состоянии понять . Определение есть:
если true, useCapture указывает, что пользователь хочет инициировать захват. После инициирования захвата все события указанного типа будут отправлены зарегистрированному прослушивателю перед отправкой в любой EventTargets под ним в дереве DOM. События, которые бурлят вверх через дерево не вызовет прослушиватель, назначенный для использования захвата.
в этом коде родительское событие срабатывает перед дочерним, поэтому я не могу понять его
поведение.Объект документ usecapture присвоено значение true и ребенка див имеет значением usecapture false и usecapture присвоено документа соблюдаются.Так почему же свойством документа является предпочтительным по сравнению с детьми.
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> 9 ответов:
события могут быть активированы в двух случаях: в начале ("захват") и в конце ("пузырь"). События выполняются в порядке их определения. Скажем, вы определяете 4 прослушивателя событий:
window.addEventListener("click", function(){alert(1)}, false); window.addEventListener("click", function(){alert(2)}, true); window.addEventListener("click", function(){alert(3)}, false); window.addEventListener("click", function(){alert(4)}, true);поля предупреждения будут появляться в следующем порядке:
2(определяется сначала с помощьюcapture=true)4(определяется второй с помощьюcapture=true)1(первое определенное событие сcapture=false)3(второе определенное событие сcapture=false)
Я считаю, что эта диаграмма очень полезна для понимания фаз захвата / цели / пузыря: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
ниже, содержимое извлечено из ссылки.
этапы
событие отправляется по пути от корня дерева к этому целевому узлу. Затем он может быть обработан локально на уровне целевого узла или от предков любого целевого объекта выше дерево. Диспетчеризация событий (также называемая распространением событий) происходит в три этапа и в следующем порядке:
- фаза захвата: событие отправляется предкам цели от корня дерева до прямого родителя целевого узла.
- целевая фаза: событие отправляется на целевой узел.
- пузырящаяся фаза: событие отправляется к цели предки от прямого родителя целевого узла до корня из дерево.
предки цели определяются до начальной отправки события. Если целевой узел удаляется во время диспетчеризации или добавляется или удаляется предок целевого объекта, распространение событий всегда будет основано на целевом узле и предках целевого объекта, определенных до отправки.
некоторые события могут не обязательно выполнять три фазы потока событий DOM, например, событие может быть только определяется для одной или двух фаз. Например, события, определенные в этой спецификации, всегда будут выполнять фазы захвата и назначения, но некоторые из них не будут выполнять фазу пузырьков ("события пузырьков" против "событий без пузырьков", см. Также событие.пузыри атрибут).
событие захвата против события пузыря
- событие захвата будет отправлено до события пузыря
- порядок распространения событий
- Родитель Захвата
- Детская Захвата
- Дети Пузырь
- Родитель Пузыря
(
stopPropagation()остановит поток )| A -----------------|--|----------------- | Parent | | | | -------------|--|----------- | | |Children V | | | | ---------------------------- | | | --------------------------------------var parent = document.getElementById('parent'), child = document.getElementById('child'); child.addEventListener('click', function(e){ console.log('Child Capture, with capture'); // e.stopPropagation(); }, true); child.addEventListener('click', function(e){ console.log('Child Bubble'); // e.stopPropagation(); }, false); parent.addEventListener('click', function(e){ console.log('Parent Capture, with capture'); // e.stopPropagation(); }, true); parent.addEventListener('click', function(e){ console.log('Parent Bubble'); // e.stopPropagation(); }, false);<div id="parent"> <button id="child">Click</button> </div>
когда вы говорите useCapture = true, события выполняются сверху вниз в фазе захвата, когда false он делает пузырь снизу вверх.
пример кода:
<div id="div1" style="background:#9595FF"> Outer Div<br /> <div id="div2" style="background:#FFFFFF"> Inner Div </div> </div>Javascript код:
d1 = document.getElementById("div1"); d2 = document.getElementById("div2");если оба имеют значение false
d1.addEventListener('click',function(){alert("Div 1")},false); d2.addEventListener('click',function(){alert("Div 2")},false);выполняет: Onclicking внутренний Div, оповещения отображаются в виде: Див 2 > Раздел 1
здесь скрипт выполняется из внутреннего элемента: Event Bubbling (useCapture имеет значение false)
div 1 имеет значение true, а div 2-false
d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},false);выполняет: Onclicking внутренний Div, оповещения отображаются в виде: Div 1 > Div 2
здесь скрипт выполняется из предка / внешнего элемента: захват событий (useCapture имеет значение true)
div 1 имеет значение false, а div 2-true
d1.addEventListener('click',function(){alert("Div 1")},false); d2.addEventListener('click',function(){alert("Div 2")},true);выполняет: Onclicking внутренний Div, оповещения отображаются в виде: Див 2 > Раздел 1
здесь скрипт выполняется из внутреннего элемента: Event Bubbling (useCapture имеет значение false)
div 1 имеет значение true, а div 2-Значение правда
d1.addEventListener('click',function(){alert("Div 1")},true); d2.addEventListener('click',function(){alert("Div 2")},true);выполняет: Onclicking внутренний Div, оповещения отображаются в виде: Div 1 > Div 2
здесь скрипт выполняется из элемента ancestor / outer: захват событий с момента установки useCapture в true
Это все о моделях событий:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow Вы можете поймать событие в фазе пузырьков или в фазе захвата. Ваш выбор.
Взгляните на http://www.quirksmode.org/js/events_order.html - вы найдете его очень полезным.
учитывая три фазы события путешествия:
- The фазы захвата: событие отправляется предкам цели от корня дерева до прямого родителя цели узел.
- The целевой фазы: событие отправляется на целевой узел.
- The пузырящейся фазы: событие отправляется предкам цели от прямого родителя объекта целевой узел к корню дерево.
useCaptureуказывает, для каких фаз событие путешествия будет:Если
true, useCapture указывает, что пользователь хочет добавить событие прослушиватель только для фазы захвата, т. е. этот прослушиватель событий не будет срабатывает во время целевых и пузырящихся фаз. Еслиfalse, в прослушиватель событий будет срабатывать только во время целевого и пузырящегося фазыисточник такой же, как и второй лучший ответ: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
резюме:
The
DOMспецификации, описанные в:https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
работает следующим образом:
событие отправляется по пути от корня (
document) от дерева до целевом узле. Целевой узел является самым глубокимHTMLэлемент, т. е. событие.цель. Диспетчеризация событий (также называется событием распространение) происходит в три фазы и в следующем порядке:
- фаза захвата: событие отправляется предкам цели из корня дерева (
document) к прямому родителю целевого узла.- цель этапа: событие отправляется на целевой узел. Целевая фаза всегда находится на самой глубокой
htmlэлемент, на котором событие было dispachted.- пузырящаяся фаза: событие отправляется предкам цели от прямого родителя целевого узла к корню дерева.
пример:
// bubbling handlers, third argument (useCapture) false (default) document.getElementById('outerBubble').addEventListener('click', () => { console.log('outerBubble'); }, false) document.getElementById('innerBubble').addEventListener('click', () => { console.log('innerBubble'); }, false) // capturing handlers, third argument (useCapture) true document.getElementById('outerCapture').addEventListener('click', () => { console.log('outerCapture'); }, true) document.getElementById('innerCapture').addEventListener('click', () => { console.log('innerCapture'); }, true)div:hover{ color: red; cursor: pointer; }<!-- event bubbling --> <div id="outerBubble"> <div id="innerBubble">click me to see Bubbling</div> </div> <!-- event capturing --> <div id="outerCapture"> <div id="innerCapture">click me to see Capturing</div> </div>приведенный выше пример действительно иллюстрирует разницу между пузырьковым событием и захватом событий. При добавлении прослушивателей событий с
addEventListener, есть третий элемент, называемый useCapture. Это аbooleanкоторый при установке вtrueпозволяет прослушивателю событий использовать захват событий вместо пузырьков событий.в нашем примере, когда мы устанавливаем аргумент useCapture в
falseмы видим, что бурление происходит. Первое мероприятие в целевой фазе запускается (журналы innerBubble), а затем через событие клокоча события на родительский элемент сгорел (журналы outerBubble).когда мы устанавливаем аргумент useCapture в
trueмы видим, что события во внешнем<div>is стреляли первыми. Это связано с тем, что событие теперь запускается в фазе захвата, а не в фазе пузырьков.
порядок определения имеет значение, только если элементы находятся на одном уровне. Если вы изменить порядок в коде вы получите те же результаты.
однако, если вы отмените параметр useCapture для двух обработчиков событий, дочерний обработчик событий ответит перед родительским. Причина этого заключается в том, что дочерний обработчик событий теперь будет запущен на этапе захвата, который предшествует фазе пузырьков, в которой будет использоваться Родительский обработчик событий вызванный.
Если вы установите useCapture в true для обоих обработчиков событий-независимо от порядка определения-Родительский обработчик событий будет запущен первым, потому что он приходит перед дочерним в фазе захвата.
и наоборот, если вы установите useCapture в false для обоих обработчиков событий-опять же, независимо от порядка определения-дочерний обработчик событий будет запущен первым, потому что он приходит перед родителем в фазе пузырьков.


Comments