e.target 属性有时返回 SVG 元素,有时返回路径元素。
这正是它的工作方式。 e.target 表示“接收”事件的元素,在大多数情况下,它是元素的某个嵌套子元素,事件侦听器附加到该元素。
查看here,了解有关事件冒泡/捕获的更多详细信息,以了解此类事件的工作原理。
基本上你只需要像这样向整个页面添加一个事件监听器:
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 的方法被描述为here。