我没有看到这个功能的来源,但我不知道它的工作原理如下:
>选择元素由他们的选择者
>将提供的事件处理程序委派给他们
>在该选择器上运行一个setInterval,并不断地取消委派,然后重新委派同一个事件
还是有一个纯JavaScript DOM的解释呢?
解决方法
我假设你的问题是关于
Event Delegation版本的.on.
在JavaScript中,大多数事件bubble在DOM层次结构中.这意味着,当某个元素可以发生泡沫的事件时,它会冒泡到DOM直到文档级别.
考虑这个基本的标记:
<div> <span>1</span> <span>2</span> </div>
现在我们应用事件委托:
$('div').on('click','span',fn);
事件处理程序仅用于div元素.由于跨度位于div的范围内,所以跨越的任何点击都会浮起来,然后触发div的点击处理程序.在那一刻,所有剩下的都是检查event.target
(或目标和delegateTarget
之间的任何元素)是否与委托目标选择器匹配.
让我们更复杂一点:
<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在我们的幕后无缝地做到这一点. =]