有人知道如何在原生JS中实现jQuery的.on()方法吗?addEventListener方法没有将子元素/选择器元素作为过滤的一种方式,我认为我没有适当的冒泡/捕获知识来完全理解其中发生了什么。我确实咨询了event.js的源代码,在那里似乎最终addEventListener确实会像往常一样被使用,但我不确定我是否完全理解了源代码。
如果本机方法不提供利用冒泡和捕获的机制,那么jQuery .on()函数真的有任何好处吗,或者它只是让它看起来是这样的吗?我的印象是
.on('parent', '.child', fn(){});比单独将事件附加到所有子级更有效,但从我对源代码的解释来看,很难说jQuery是否以某种方式对此进行了管理,以提高性能,或者只是为了可读性。
有没有一种标准的方法来在父元素上实现事件,从而利用其子元素的冒泡/捕获阶段,而不是必须将事件附加到每个单独的子元素?
发布于 2014-01-31 04:40:43
要本机执行事件委派,请执行以下操作:
parent.addEventListener('click', function(e) {
if(e.target.classList.contains('myclass')) {
// this code will be executed only when elements with class
// 'myclass' are clicked on
}
});您所指的效率与您添加的事件处理程序的数量有关。想象一下一个有100行的表。将单个事件处理程序附加到表元素,然后“委托”到每行,比附加100个事件处理程序(每行1个)要有效得多。
事件委派之所以有效,是因为单击事件实际上会同时在子级和父级上触发(因为您是在父级中的某个区域上单击)。上面的代码片段在父级的单击事件上触发,但仅当事件目标的条件返回true时才执行,从而模拟直接附加的事件处理程序。
冒泡/捕获是一个相关的问题,但只有在多个事件处理程序触发的顺序很重要的情况下,您才需要担心它。如果您对理解冒泡与捕获感兴趣,我建议您进一步阅读event order。
事件委托最常见的好处是,它可以处理附加事件处理程序之后添加到DOM中的新元素。以上面包含100行的表为例,该表具有单击处理程序。如果我们使用直接的事件处理程序附件(100个事件处理程序),那么添加的新行将需要手动添加事件处理程序。如果我们使用委托事件,那么新行将自动“拥有”事件处理程序,因为从技术上讲,它已被添加到将拾取所有未来事件的父处理程序中。根据Felix Kling的建议,请阅读What is DOM Event Delegation以获取更多信息。
发布于 2021-12-16 14:06:14
添加到公认的答案中:由于实际的事件目标通常嵌套在您想要将侦听器绑定到它的元素中,因此最好查询父级(Element.closest()包括元素本身)。同样,这也适用于复杂的CSS选择器,而不仅仅是单个类。
<button><span>button with</span><span>multiple click targets</span></button>
function addListener(el, type, callbackFn, selector) {
el.addEventListener(type, e => {
const target = e.target.closest(selector);
if (target) callbackFn.call(target, e);
}, true);
}
addListener(document, "click", e => console.log("clickediclick"), "button");https://stackoverflow.com/questions/14174056
复制相似问题