Свойство e.target иногда возвращает элемент SVG, а иногда возвращает элемент пути.
Именно так оно и должно работать.e.target
представляет элемент, который »получил« событие, и в большинстве случаев является вложенным дочерним элементом элемента, к которому подключен слушатель события.
Посмотрите здесь для получения более подробной информации о пузырях / захвате событий, чтобы получить представление о том, как такие события работают.
В основном вам нужно добавить только одного прослушивателя событий на всю страницу, например:
window.addEventListener('click', e => console.log(e.target));
дляпоймать каждый нажмите на страницу.оттуда вам нужен способ делегировать событие соответствующему обработчику.Я часто чувствовал себя счастливым с таким решением:
образец HTML
<div class="btns">
<div data-click-handler="btn">
<span>
<p>some sample content</p>
</span>
</div>
<div data-click-handler="btn2">
<ul>
<li>…</li>
</ul>
</div>
</div>
JS
const handlers = {
btn: e => alert('btn clicked'),
btn2: e => alert('btn2 clicked')
}
window.addEventListener('click', e => {
let
c = e.target,
//that could be an array as well
//if you want all the handlers on
//»way upwards« to be called
handler = null
;
//as long as there is a Node
while (c && c.hasAttribute) {
//check if it should listen to events
if (c.hasAttribute('data-click-handler')) {
//get the handler if it exists
let key = c.getAttribute('data-click-handler');
if (handlers.hasOwnProperty(key)) {
handler = handlers[key];
//break the loop to keep the reference to
//»desired target«
break;
}
}
//go upwards in the tree
c = c.parentNode;
}
//finally call the handler, if any
if (handler !== null) handler(c);
});
Это всего лишь иллюстрация / схема способа реализации делегирования событий, чтобы избавить от необходимости регистрировать выделенный обработчик событий для каждого элемента, который должен вызывать некоторый код в событиях.Если у вас есть целая куча элементов, которые должны реагировать на определенные события, вам может понадобиться такая техника для преодоления проблем с производительностью.
В принципе, существует множество способов сделать такую вещь, другой с помощью <element>.matches() API
описано здесь .