我还没有看到这个函数的源码,但我想知道,它的工作原理是这样的:
- 通过选择器选择元素
- 将提供的事件处理程序委托(delegate)给他们
- 在该选择器上运行
setInterval
并不断取消委托(delegate),然后重新委托(delegate)同一事件
或者有对此的纯 JavaScript DOM 解释吗?
最佳答案
我假设您的问题是关于 Event Delegation .on
.
在 JavaScript 中,大多数事件 bubble在 DOM 层次结构中。这意味着,当某个元素触发一个可以冒泡的事件时,它将向上冒泡到 DOM,直到 document
级别。
考虑这个基本标记:
<div>
<span>1</span>
<span>2</span>
</div>
现在我们应用事件委托(delegate):
$('div').on('click', 'span', fn);
事件处理程序仅附加到 div
元素。由于 span
位于 div
内部,因此在 span 中的任何点击都会向上冒泡到 div
,从而触发 div
code> 的点击处理程序。此时,剩下的就是检查 event.target
是否(或目标和 delegateTarget
之间的任何元素)与委托(delegate)目标选择器匹配。
让我们把事情变得更复杂一点:
<div id="parent">
<span>1</span>
<span>2 <b>another nested element inside span</b></span>
<p>paragraph won't fire delegated handler</p>
</div>
基本逻辑如下:
//attach handler to an ancestor
document.getElementById('parent').addEventListener('click', function(e) {
//filter out the event target
if (e.target.tagName.toLowerCase() === 'span') {
console.log('span inside parent clicked');
}
});
尽管当 event.target
嵌套在过滤器中时,上述内容将不匹配。我们需要一些迭代逻辑:
document.getElementById('parent').addEventListener('click', function(e) {
var failsFilter = true,
el = e.target;
while (el !== this && (failsFilter = el.tagName.toLowerCase() !== 'span') && (el = el.parentNode));
if (!failsFilter) {
console.log('span inside parent clicked');
}
});
编辑:更新代码以仅匹配后代元素,如 jQuery 的 .on
那样。
注意:这些片段用于解释目的,不用于现实世界。当然,除非您不打算支持旧版 IE。对于旧版 IE,您需要针对 addEventListener
/attachEvent
以及 event.target || 进行功能测试。 event.srcElement
,以及可能的一些其他怪癖,例如检查事件对象是否传递给处理函数或在全局范围内可用。值得庆幸的是 jQuery 在幕后无缝地为我们完成了这一切。 =]
关于javascript - jQuery.on() 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15112067/