Не в состоянии понять параметр 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>
594   9  

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

ниже, содержимое извлечено из ссылки.

этапы

событие отправляется по пути от корня дерева к этому целевому узлу. Затем он может быть обработан локально на уровне целевого узла или от предков любого целевого объекта выше дерево. Диспетчеризация событий (также называемая распространением событий) происходит в три этапа и в следующем порядке:

  1. фаза захвата: событие отправляется предкам цели от корня дерева до прямого родителя целевого узла.
  2. целевая фаза: событие отправляется на целевой узел.
  3. пузырящаяся фаза: событие отправляется к цели предки от прямого родителя целевого узла до корня из дерево.

graphical representation of an event dispatched in a DOM tree using the DOM event flow

предки цели определяются до начальной отправки события. Если целевой узел удаляется во время диспетчеризации или добавляется или удаляется предок целевого объекта, распространение событий всегда будет основано на целевом узле и предках целевого объекта, определенных до отправки.

некоторые события могут не обязательно выполнять три фазы потока событий DOM, например, событие может быть только определяется для одной или двух фаз. Например, события, определенные в этой спецификации, всегда будут выполнять фазы захвата и назначения, но некоторые из них не будут выполнять фазу пузырьков ("события пузырьков" против "событий без пузырьков", см. Также событие.пузыри атрибут).

событие захвата против события пузыря

  • событие захвата будет отправлено до события пузыря
  • порядок распространения событий
    1. Родитель Захвата
    2. Детская Захвата
    3. Дети Пузырь
    4. Родитель Пузыря

(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 - вы найдете его очень полезным.

учитывая три фазы события путешествия:

  1. The фазы захвата: событие отправляется предкам цели от корня дерева до прямого родителя цели узел.
  2. The целевой фазы: событие отправляется на целевой узел.
  3. 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 элемент, т. е. событие.цель. Диспетчеризация событий (также называется событием распространение) происходит в три фазы и в следующем порядке:

  1. фаза захвата: событие отправляется предкам цели из корня дерева (document) к прямому родителю целевого узла.
  2. цель этапа: событие отправляется на целевой узел. Целевая фаза всегда находится на самой глубокой html элемент, на котором событие было dispachted.
  3. пузырящаяся фаза: событие отправляется предкам цели от прямого родителя целевого узла к корню дерева.

Event bubbling, event capturing, event target

пример:

// 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

    Ничего не найдено.