代码之家  ›  专栏  ›  技术社区  ›  xkeshav

jquery的“click”、“bind”、“live”、“delegate”、“trigger”和“on”函数之间的区别(举个例子)?

  •  139
  • xkeshav  · 技术社区  · 14 年前

    我已经阅读了每个函数的文档 jQuery official website ,但以下函数之间没有类似的比较列表:

    $().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 我认为这一个以某种方式涵盖了上述所有功能需求。

    5 回复  |  直到 11 年前
        1
  •  160
  •   Community Paul Sweatte    7 年前

    在你读这个之前, pull this list of events up in another page, the API itself is tremendously helpful, and all of what I'm discussing below is linked directly from this page .

    第一, .click(function) 实际上是 .bind('click', function) ,它们是等效的。在绑定处理程序时使用它们 直接到元素 ,像这样:

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

    如果这个元素被替换或丢弃,这个处理程序将不再存在。还有一些不存在的元素 运行此代码时 附加处理程序(例如选择器找到它)将无法获取处理程序。

    .live() .delegate() 有着相似的联系, 委托() 实际使用 LIVER() 在内部,他们都会监听泡沫事件。 这适用于新旧元素 它们以同样的方式泡沫事件。当您的元素可能发生更改时,例如添加新行、列表项等,您可以使用这些。如果您没有将保留在页面中且在任何时候都不会被替换的父/公共祖先,请使用 LIVER() ,像这样:

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

    但是,如果在某个地方确实有一个父元素不能被替换(因此它的事件处理程序不会再见),则应该使用 委托() ,像这样:

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

    这和 LIVER() ,但在捕获和执行处理程序之前,事件气泡的次数更少。这两种方法的另一个常见用法是,假设您的类在一个元素上发生了更改,不再与最初使用的选择器相匹配……使用这些方法可以计算选择器 在事件发生时 ,如果匹配,则处理程序将运行…因此元素不再匹配选择器,它将不再执行。用 .click() 但是,事件处理程序是直接绑定在dom元素上的,它与用于查找它的选择器不匹配这一事实是不相关的……事件是绑定的,它将一直保留到该元素消失或处理程序通过 .unbind() .

    另一个常见的用途是 LIVER() 委托() 性能 . 如果你正在处理 太多了 在元素中,直接将单击处理程序附加到每个元素既昂贵又耗时。在这些情况下,设置一个 单一的 处理,让气泡来做这个工作, take a look at this question where it made a huge difference 这是一个很好的应用实例。


    触发 -对于更新的问题

    有两个主要的事件处理程序触发函数可用, they fall under the same "Event Handler Attachment" category in the 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
    

    You can view a listing including these shortcuts here .

    至于区别, 三角级数() 触发事件处理程序(但大多数情况下不是默认操作,例如,在单击时将光标放在正确的位置 <textarea> )它使事件处理程序按绑定顺序发生(与本机事件一样),激发本机事件操作,并使DOM冒泡。

    .triggerhandler()。 通常是为了另一个目的,这里您只是尝试激发绑定的处理程序,它不会导致本机事件激发,例如提交表单。它不会在DOM中冒泡,也不可链接(它返回该事件的最后一个绑定事件处理程序返回的任何内容)。例如,如果你想触发 focus 事件,但实际上不是聚焦对象,您只需要绑定的代码 .focus(fn) 要跑,这就可以了,但是 三角级数() 这样做的同时也会聚焦元素并冒泡。

    下面是一个现实世界的例子:

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

    这将运行任何提交处理程序,例如 jQuery validation plugin ,然后尝试提交 <form> . 但是如果你 只是 想要验证,因为它通过 submit 事件处理程序,但不提交 <形式& gt; 之后,你可以使用 .triggerHandler('submit') ,像这样:

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

    如果验证检查没有通过,插件会阻止处理程序通过轰炸来提交表单,但是使用这个方法,我们不关心它做了什么。不管它是否中止,我们不是 尝试 为了提交表单,我们只想触发它来重新验证,而不做其他任何事情。( 免责声明: 这是一个多余的例子,因为 .validate() 插件中的方法,但这是一个很好的意图说明)

        2
  •  28
  •   Fyodor Soikin    14 年前

    前两个是等价的。

    // 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”的链接时,您希望它自动具有相同的事件处理程序。当您有某种类型的列表或表时,这是非常常见的,在这些列表或表中,您动态地添加行或单元格,但希望它们都以相同的方式工作。您可以使用 方法:

    <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中的事件具有“冒泡”的有趣特征。考虑一下:

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

    如果单击“文本”,则首先<b>元素将获得“单击”事件。之后,<a>元素将得到一个“click”事件。然后<div>元素将得到一个“click”事件。等等-一直到<body>元素。这就是jquery捕获事件的地方,看看是否有任何“活动”处理程序应用于最初导致事件发生的元素。整洁!

    最后, .delegate 方法。它只需要您元素中符合给定选择器的所有子元素,并向它们附加一个“活动”处理程序。看一看:

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

    问题?

        3
  •  8
  •   Jonathan Tonge    12 年前

    从jquery 1.7开始,不推荐使用.live()方法。如果您使用的是jquery版本<1.7,则正式建议您使用.delegate()over.live()。

    .live()现已替换为.on()。

    最好直接到jquery站点获取更多信息,但下面是.on()方法的当前版本:

    .on( events [, selector] [, data], handler(eventObject) )
    .on( events-map [, selector] [, data] )
    

    http://api.jquery.com/on/

        4
  •  2
  •   Peter Mortensen Milad    13 年前

    $().click(fn) $().bind('click', fn) 乍一看是一样的,但是 $.bind 版本更强大的原因有两个:

    1. $().bind() 允许您将一个处理程序分配给多个事件,例如, $().bind('click keyup', fn) .
    2. $() 支持命名空间事件-如果只想删除(取消绑定)元素绑定到的某些事件处理程序,这是一个功能强大的功能-请在中阅读更多信息 Namespaced Events .

    Live vs Delegate:此问题已在其他答复中得到答复。

        5
  •  1
  •   Dan Beam    14 年前

    在这里,阅读API可能会有所帮助。但是,我知道我的头,所以你可以继续懒惰(耶!).

    $('#something').click(fn);
    $('#something').bind('click',fn);
    

    这里没有区别(我知道)。 .click 只是一种方便/帮助方法 .bind('click'

    // even after this is called, all <a>s in
    // <div class="dynamic_els"> will continue
    // to be assigned these event handlers
    
    $('div.dynamic_els a').live(‘click’,fn);
    

    这是非常不同的,因为 .live 将事件添加到传入的选择器(此处没有),并在插入/删除节点时继续查看DOM。

    $('#some_element').delegate('td','click',fn);
    

    这只是因为您分配事件处理程序的方式不同。 .delegate 以DOM事件冒泡为中心。基本原则是,每个事件都通过DOM树向上气泡,直到到达根元素为止。( document window <html> <body> ,我记不清了)。

    不管怎样,你都要把 onclick 处理程序到 <td> S内 $('#some_element') (您必须指定一个选择器,尽管您可以说 $(document) )单击它的一个子项时,事件将冒泡到 <TD & GT; . 然后可以提取事件的源元素(jquery自动为您提取)。

    当存在大量元素并且这些事件只会经历几个(或一个中心)点时,这很有用。这样可以节省浏览器的工作和内存,将这些事件处理程序合并为较少的对象。