Определить путь события в DOM Event bubbling

Я пытаюсь выяснить путь, по которому событие пузырилось. Например, у меня есть отметка, например

 <div id="container" onclick="func">
        <div id="div1"></div>
        <div id="div2">
            <div id="div2.1"></div>
            <span id="span2.2"></span>
            <div id="div2.3">
                <button id="btn2.3.1"></button>
            </div>
        </div>
    </div>

Теперь, если щелкнул btn2.3.1, я хочу увидеть весь путь, по которому событие пузырилось, через которое находится btn2.3.1 → div2.3 → div2 → container. Есть ли способ сделать это, только помещая обработчик в контейнер? (Нет JQuery)

Я нашел массив event.path. Что делает этот материал, но не смог найти много деталей об этом. Он перекрещивается с браузером? Каков правильный способ достижения этого?

Ответы

Ответ 1

event.path || event.composedPath()

event.path

Отключено/не включено примечанием в документации проекта полимера и через статью HTML5Rocks, path - это семейное дерево в форме Array.

Похоже, что это "расширение интерфейса event", доступное только через Веб-компонент Shadow DOM, и является стандартным только в этом отношении (по-видимому), не так много документации доступно, и это не отображается (по умолчанию) во всех браузерах.

event.composedPath() на помощь!

На другой вопрос об использовании path был дан ответ с предложением использовать composedPath...

Документация MDNо event.composedPath() описывает это следующим образом:

Метод composedPath() интерфейса Event возвращает путь событий, который является массивом объектов, для которых будут вызываться прослушиватели. Это не включает узлы в теневых деревьях, если теневой корень был создан с закрытым ShadowRoot.mode.

Он описан WHATWG в их документации "спецификации DOM" о "пути событий" следующим образом:

Returns the invocation target objects of events path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow rootmode is "closed" that are not reachable from events currentTarget.

Могу ли я использовать... заявляет, что поддержка браузера composedPath() широко распространена, IE и Edge отстают без ожидаемой поддержки, и MDN соглашается.

В документации WHATWG о "отправке событий" подробно описываются условия, при которых к "событию path" будут добавляться элементы appended.

Details correct September 25, 2019

Практическая демонстрация

const green = document.getElementById( 'green' ),
      msg = document.querySelector( 'output' );

document.getElementById( 'red' ).addEventListener( 'click', evt => {
  msg.innerHTML = '"' + evt.target.id + '" got poked, and "green" was' +
  
  /* access to the event path */
  ( ~evt.composedPath().indexOf( green ) ? '' : "<b>n't</b>" )
  
  + ' in the path.';
} );
div { display: inline-block; padding: 1em 3em 1em 1em; cursor: pointer }
output { font-family: monospace; display: block; margin-top: 1em }
#red { background: red }
#green { background: green }
#blue { background: blue }
<div id="red">
  <div id="green">
    <div id="blue"></div>
  </div>
</div>
<output>Poke the DOM!</output>

Ответ 2

function handleClicks(e) {
    var path = [];
    var node = e.target;
    while(node != document.body) {
       path.push(node);
       node = node.parentNode;
    }
    console.log(path);
}

document.body.addEventListener('click', handleClicks);

Ответ 4

Предположим, что нам нужно найти путь к событию внутри тега HTML-таблицы.

<tabe id="tab">
.
.
.
</table>

Следующий код JavaScript будет возвращать элемент события после каждого события.

window.onload = function(){
var tab = document.getElementById('tab');
tab.onclick = function(event) {
var target = getTargetElement(event);
console.log(target);
};
}
function getTargetElement(e) {
e = e || window.event;
return e.target || e.srcElement;
}