为什么" on"事件支持授权,但它的"捷径"方法不要?

时间:2014-04-17 00:30:26

标签: jquery javascript-events event-delegation

根据jQuery's API siteon()事件在附加到DOM节点时支持委派。据我所知,这意味着您可以拥有2个DOM节点,事件从内部节点或其内部的某个位置开始,然后冒泡到外部节点。在此之前,当您只为on()指定一个节点时,事件会冒泡到文档的绝对外部节点,称为document(我相信如果您有相同的事情则会发生document作为“外部”DOM节点)。 on()的“快捷方式”事件,例如click()change(),似乎不会实现委派,这意味着事件必须一直冒泡到文档的顶部。如果我已经剔除了这个解释,我相信我有,请纠正我。这是为什么?

例如,我可以

$("form").on("click", "button", function() {
    window.location.href = "submit-page.php";
});

是委托,或

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

事件将从文档中冒出来。但是,click()似乎只能使用第二种形式

$("button").click(function() {
    window.location.href = "submit-page.php";
});

3 个答案:

答案 0 :(得分:2)

.on()仅在与两个选择器一起使用时支持委托:

$("#parent").on("click", "#child", fn);

.click()这样的快捷方式不支持两种选择器语法,因此不会以同样的方式支持委派。


在您的代码示例中,这两个代码块没有相同的行为:

$("form").on("click", "button", function() {
    window.location.href = "submit-page.php";
});

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

第一个使用事件委托,并将响应源自"按钮的传播事件"即使在添加事件处理程序后很长时间添加了该按钮也是对象。第二种是仅直接事件处理,并且只将事件处理程序附加到最初运行事件处理代码时存在的对象。这是直接事件处理和委托事件处理之间的区别。

另一个细微差别是第一个只响应button中包含的form事件(事件通过form对象传播)而第二个事件响应事件来自安装事件处理程序时存在的页面中的任何button,即使不在form中的页面也是如此。


在您的代码示例中,这两个行为具有相同的行为(两者都是直接事件处理程序,并且只适用于安装事件处理程序时存在的对象):

$("button").on("click", function() {
    window.location.href = "submit-page.php";
});

$("button").click(function() {
    window.location.href = "submit-page.php";
});

答案 1 :(得分:1)

click存在之前,bind函数曾是on的别名。 bind会将事件直接附加到指定的元素。

此处bind的更多信息:http://api.jquery.com/bind/

看起来他们似乎从未觉得需要将功能扩展到添加on之后已经存在的功能,只需将内部代码移植到使用on而不是bind

在任何一种情况下,我通常只使用on并跳过click等快捷方式。

答案 2 :(得分:1)

非授权方法没有冒泡。它们只是将处理程序附加到绑定它们的特定元素。冒泡由on的委派形式使用:当您单击按钮时,事件会冒泡到表单。然后附加在那里的通用处理程序检查事件的目标是否与selector参数匹配,在这种情况下它运行你提供的处理程序。

委托比普通绑定有更多的运行时开销,因为内部jQuery处理程序必须在包含元素中的任何位置单击时运行 - 它不能将处理程序附加到更具体的元素,因为它们可能不存在于你建立绑定的时间。由于这仅在特殊情况下需要,因此快捷语法不提供执行此操作的方法。

您可能想向jQuery论坛提交建议。增强快捷方法以允许语法如下:

可能不会太困难
$("form").click("button", function() { ... });

这将是简短的:

$("form").on("click", "button", function() { ... });

据我所知,这与任何现有语法都没有冲突。