jQuery“点击”,“绑定”,“实时”,“委托”,“触发器”和“打开”函数之间的区别(举个例子)?

2022-08-30 04:11:32

我已经在jQuery官方网站上阅读了每个函数的文档,但是以下函数之间没有这样的比较列表:

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

请避免任何参考链接。

上述所有函数究竟是如何工作的,在哪种情况下应该首选哪种函数?

注意:如果有任何其他功能具有相同的功能或机制,请详细说明。

更新

我还看到了一个功能。它的工作原理是否类似于上述功能?$.trigger

更多更新

现在.on被添加到v1.7中,我认为这个以某种方式涵盖了上述所有功能要求。


答案 1

在你阅读这篇文章之前,把这个事件列表拉到另一个页面,API本身是非常有帮助的,我下面讨论的所有内容都是直接从这个页面链接的

首先,.click(function)实际上是.bind('click',function)的快捷方式,它们是等效的。在将处理程序直接绑定到元素时使用它们,如下所示:

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

如果此元素被替换或丢弃,则此处理程序将不再存在。此外,在运行此代码以附加处理程序时不存在的元素(例如,选择器当时找到了它)将不会获取处理程序。

.live().delegate() 是类似的相关关系,.delegate() 实际上在内部使用 .live(),它们都侦听事件冒泡。这适用于新旧元素,它们以相同的方式冒泡事件。当您的元素可能发生变化时,您可以使用它们,例如添加新行,列表项等。如果您没有将保留在页面中且在任何时候都不会被替换的父/共同祖先,请使用 .live(),如下所示:

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

但是,如果您确实在某个地方有一个没有被替换的父元素(因此它的事件处理程序不会再见),则应使用.delegate()来处理它,如下所示:

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

这几乎与 .live() 相同,但在捕获和执行处理程序之前,事件冒泡的次数较少。这两个功能的另一个常见用法是,您的类在元素上发生了变化,不再与您最初使用的选择器匹配......使用这些方法,选择器在事件发生时进行评估,如果它匹配,则处理程序运行...因此,不再与选择器匹配的元素很重要,它将不再执行。但是,使用.click(),事件处理程序被直接绑定在DOM元素上,它与用于查找它的任何选择器不匹配的事实是无关紧要的...事件已绑定并一直保留,直到该元素消失,或者通过 .unbind() 删除处理程序。

.live() 和 .delegate() 的另一个常见用途是性能。如果您正在处理大量元素,则将单击处理程序直接附加到每个元素既昂贵又耗时。在这些情况下,设置单个处理程序并让冒泡完成工作更经济,看看这个问题,它产生了巨大的差异,这是应用程序的一个很好的例子。


触发 - 对于更新的问题

有 2 个主要的事件处理程序触发函数可用,它们在 API 中属于相同的“事件处理程序附件”类别,它们是 .trigger().triggerHandler()。.trigger('eventName') 为常见事件内置了一些快捷方式,例如:

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

您可以在此处查看包含这些快捷方式的列表

至于区别,.trigger()会触发事件处理程序(但大多数时候不是默认操作,例如,将光标放在单击中的正确位置)。它使事件处理程序按它们绑定的顺序发生(就像本机事件一样),触发本机事件操作,并冒泡 DOM。<textarea>

.triggerHandler() 通常用于不同的目的,在这里您只是尝试触发绑定的处理程序,它不会导致本机事件触发,例如提交表单。它不会冒泡 DOM,并且不可链接(它返回该事件的最后绑定事件处理程序返回的任何内容)。例如,如果你想触发一个事件,但实际上并没有聚焦对象,你只想运行用.focus(fn)绑定的代码,这将这样做,而.trigger()会这样做,并且实际上聚焦元素并冒泡。focus

下面是一个真实世界的示例:

$("form").submit(); //actually calling `.trigger('submit');`

这将运行任何提交处理程序,例如jQuery验证插件,然后尝试提交.但是,如果您只想验证,因为它是通过事件处理程序挂接的,但之后不提交,则可以使用.triggerHandler('submit'),如下所示:<form>submit<form>

$("form").triggerHandler('submit');

如果验证检查没有通过,该插件会阻止处理程序通过轰炸来提交表单,但是使用此方法,我们并不关心它的作用。无论它是否中止,我们都不会尝试提交表单,我们只想触发它重新验证,而不执行任何其他操作。(免责声明:这是一个多余的例子,因为插件中有一个方法,但它是一个不错的意图说明).validate()


答案 2

前两个是等效的。

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

但是,第二个事件可用于通过指定多个空格分隔的事件名称同时绑定到多个事件:

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

该方法更有趣。请考虑以下示例:.live

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

脚本的第二行执行后,第二个链接还将具有CSS类“myLink”。但它将没有事件处理程序,因为在附加事件时它没有该类。

现在考虑一下您希望它反过来:每次页面上的某个位置出现带有类“myLink”的链接时,您都希望它自动具有相同的事件处理程序。当您具有某种列表或表时,这种情况很常见,您可以在其中动态添加行或单元格,但希望它们都以相同的方式运行。与其每次都重新分配事件处理程序,不如使用以下方法:.live

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

在此示例中,第二个链接还将在获得“myLink”类后立即获取事件处理程序。:-)

当然,它不是那么字面上的意思。真正的作用不是将处理程序附加到指定的元素本身,而是附加到HTML树的根(“body”元素)。DHTML中的事件具有“冒泡”的有趣功能。请考虑以下情况:.live

<div> <a> <b>text</b> </a> </div>

如果单击“text”,则首先<b>元素将获得“click”事件。之后,<a>元素将获得“单击”事件。之后,<div>元素将获得“单击”事件。以此类推 - 一直到<体>元素。这就是jQuery将捕获事件并查看是否有任何“实时”处理程序适用于首先导致事件的元素。整洁!

最后是方法。它只是获取元素中符合给定选择器的所有子元素,并向它们附加一个“实时”处理程序。看一看:.delegate

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );

// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

问题?