javascript - jQuery.on() 是如何工作的?

标签 javascript jquery dom-events event-delegation jquery-on

我还没有看到这个函数的源码,但我想知道,它的工作原理是这样的:

  1. 通过选择器选择元素
  2. 将提供的事件处理程序委托(delegate)给他们
  3. 在该选择器上运行 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');
    }
});

Fiddle

编辑:更新代码以仅匹配后代元素,如 jQuery 的 .on 那样。

注意:这些片段用于解释目的,不用于现实世界。当然,除非您不打算支持旧版 IE。对于旧版 IE,您需要针对 addEventListener/attachEvent 以及 event.target || 进行功能测试。 event.srcElement,以及可能的一些其他怪癖,例如检查事件对象是否传递给处理函数或在全局范围内可用。值得庆幸的是 jQuery 在幕后无缝地为我们完成了这一切。 =]

关于javascript - jQuery.on() 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15112067/

相关文章:

php - 使用 .htaccess 压缩文件时出现 500 错误

javascript - 将正则表达式输出返回到第一个案例

javascript - analytics.js 事件并不总是发送

javascript - 使用 socket.io 事件更新状态

javascript - 如何在数据表列中仅显示前 30 个字符,然后放置“阅读更多”按钮?

javascript - 错误计数的 jQuery 验证编号

javascript - 确保附加行始终是动态创建的行组成的表中的最后一行。 。分离()

javascript - 如何在其他标签的 <a> 标签上创建相同的鼠标悬停行为?

javascript - 拒绝 keyDown 事件上的 "control"键

javascript - 类型错误 : Cannot read property 'error' of undefined on React Chrome Extension