2

Как я понимаю, DOM Level 2 обработки событий работы в следующем порядке:В обработке событий JavaScript DOM Level 2, почему цель сначала «пузырится», а затем «захватывает»?

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

пример на: https://jsfiddle.net/uwe5dmxw/
(я буду включать код в конце этого вопроса)

Но если я нажму на элемент «ребенок» (самый низкий уровень потомка) на текущей Google Chrome, Firefox, Safari, и даже в IE 11, я получаю последовательный результат в таком порядке:

  1. HTML захватив
  2. ТЕЛА захватывая
  3. родителя захватывая
  4. цели кипящего
  5. цели захват
  6. родителя кипящего
  7. ТЕЛА кипящего
  8. HTML кипящего

То есть порядок «целевой захват» и «целевое бульканье» восстанавливается.

Как я понял, хотя уровень DOM Level 2 сказал, что событие достигает цели только один раз, но большинство браузеров реализуют его как достижение его дважды, один раз во время захвата события и один раз во время барботажа событий. Но дело в том, почему «целевой захват» и «целевое пузырение» отменены?


Код: (но только демо, вы не должны смотреть на него, если нет необходимости)

<div id="hi"> 
    hello 
    <div id="child"> 
    child 
    </div> 
</div> 

JavaScript:

var parentElement = document.getElementById("hi"), 
    childElement = document.getElementById("child"), 
    htmlElement = document.getElementsByTagName("html")[0], 
    bodyElement = document.getElementsByTagName("body")[0]; 

// ------------------ Bubble -------------------- 

htmlElement.addEventListener("click", function() { 
    console.log("<html> clicked " + new Date().getTime(), this); 
}); 

bodyElement.addEventListener("click", function() { 
    console.log("<body> clicked " + new Date().getTime(), this); 
}); 

parentElement.addEventListener("click", function() { 
    console.log("Parent clicked " + new Date().getTime(), this); 
}); 

childElement.addEventListener("click", function() { 
    console.log("Child clicked at " + new Date().getTime(), this); 
}); 

// ------------------ Use Capture -------------------- 

htmlElement.addEventListener("click", function() { 
    console.log("<html> (useCapture) clicked " + new Date().getTime(), this); 
}, true); 

bodyElement.addEventListener("click", function() { 
    console.log("<body> (useCapture) clicked " + new Date().getTime(), this); 
}, true); 

parentElement.addEventListener("click", function() { 
    console.log("Parent (useCapture) clicked " + new Date().getTime(), this); 
}, true); 

childElement.addEventListener("click", function() { 
    console.log("Child (useCapture) clicked at " + new Date().getTime(), this); 
}, true); 

ответ

3

Когда событие происходит на объект с несколькими обработчиками событий, обработчики событий запускаются в том порядке, в котором они прикреплены. Вы не видите отдельное событие на child. Вы видите одно и то же событие (событие click), которое отправляется обоим обработчикам событий, но отправляется в том порядке, в котором привязаны обработчики событий.

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

Если вы регистрируете e.eventPhase для каждого из двух обработчиков целевых событий, вы увидите, что оно регистрирует значение 2, что означает, что оно находится «в цель» (не пузыря или захвата). См. doc on MDN для получения дополнительной информации о e.eventPhase.

+0

интересно ... так что флаг 'useCapture' игнорируется.Он просто рассматривает его как небублирующую и не захватывающую фазу, а как «фазу at-target» –

+1

@ 太極 者 無極 而 生 - То, что кажется, что когда событие находится в мишени, вызывается оба типа обработчиков событий (захват и не-захват), в порядке присвоения обработчикам событий. На цель не помечен захват события. – jfriend00

+1

это правда ... 'useCapture' не игнорируется ... потому что в то время, когда вы делаете' addEventListener() ', не сообщается, является ли этот элемент целью, пока что-то не произойдет с ним или его потомством –