[译] Jquery中 .bind() .live() .delegate() 和 .on() 之间的区分

简介

我相识到很多网页开发者对jquery中的 .bind() .live() .delegate().on() 要领存在很多的疑惑。这些疑惑通常是关于它们之间真正的区分是什么啊,什么时刻该运用它们啊。

在我们深切相识这些要领之前,我们先来一段罕见的的HTML,作为我们编写jquery示例要领运用的样本。

<ul id="members" data-role="listview" data-filter="true">
    <!-- ... 其他li ... -->
    <li>
        <a href="detail.html?id=10">
            <h3>John Resig</h3>
            <p><strong>jQuery Core Lead</strong></p>
            <p>Boston, United States</p>
        </a>
    </li>
    <!-- ... 其他li ... -->
</ul>

运用Bind要领

.bind()要领将事宜范例和一个事宜处置惩罚函数直接注册到了被选中的DOM元素中。这个要领被运用得最久,在此期间,它很好的处理了种种跨浏览器的题目。当运用它来衔接事宜处置惩罚函数时,它依然异常简约,然则也存在着一些机能方面的题目,将在下面排列出来。


/* .bind() 要领将事宜范例和一个事宜处置惩罚函数直接注册到了被选中的DOM元素中。 
   .click() 要领只是.bind() 要领的简写。
*/

$( "#members li a" ).bind( "click", function( e ) {} ); 
$( "#members li a" ).click( function( e ) {} ); 

.bind()要领将会把事宜处置惩罚函数衔接到一切婚配的a标签。这类体式格局并不好。如许做的话,它不仅在一切婚配的元素中隐含地迭代附加事宜处置惩罚函数,而且这些操纵异常糟蹋(过剩),由于这些雷同的事宜处置惩罚函数是被一遍一遍的反复的增加到一切婚配的标签上。

长处:

  • 适用于种种浏览器
  • 衔接事宜处置惩罚函数异常轻易快捷
  • 能够运用 .click(), .hover()等简写要领来更方面地衔接事宜处置惩罚函数
  • 关于一个简朴的ID挑选器,运用.bind() 要领不仅能够很快地衔接事宜处置惩罚函数,而且当事宜被触发时, 事宜处置惩罚函数几乎是立时就被挪用了

瑕玷:

  • 如许要领会将一切的事宜处置惩罚函数附加到一切婚配的元素
  • 不能够动态地婚配雷同挑选器的元素
  • 当操纵大批婚配的元素时会有机能方面的题目
  • 附加操纵是在前期完成的,这能够致使页面加载时存在机能题目

运用Live要领

.live()要领运用了事宜托付的观点来实行其所谓的“魔法”。你挪用.live()要领的体式格局就像是挪用.bind()要领那样轻易。但是在这外表之下,.live()要领与前者的完成体式格局大不雷同。.live()要领将与事宜处置惩罚函数关联的挑选器和事宜信息一同附加到文档的根级元素(即document)。经由历程将事宜信息注册到document上,这个事宜处置惩罚函数将许可一切冒泡到document的事宜挪用它(比方托付型、流传型事宜)。一旦有一个事宜冒泡到document元素上,Jquery会依据挑选器或许事宜的元数据来决议哪个事宜处置惩罚函数应当被挪用,假如这个事宜处置惩罚函数存在的话。这个分外的事变将会在用户交互时对机能方面形成肯定的影响,然则初始化注册事宜的历程相本地快。

/* 要领将与事宜处置惩罚函数关联的挑选器和事宜信息一同附加到文档的根级元素(即document) 
   ( "#members li a" & "click" ) */ 

$( "#members li a" ).live( "click", function( e ) {} );

.bind()这个例子与上面.bind()要领的例子对照的话有一个长处在于它仅仅把事宜处置惩罚函数附加到document元素一次,而不是许屡次。如许不仅更快,而且还削减了机能的糟蹋。但是,运用这个要领也会带来很多题目,下面将逐一列出。

长处:

  • 一切的事宜处置惩罚函数都只会被注册一次,而不是像.bind()那样举行屡次注册
  • .bind()要领升级到.live()要领异常轻易,你仅须要将”bind”替代为”live”就能够了
  • 那些被动态增加到DOM的元素也将被奇异的婚配到,由于实在的事宜信息是被注册到document元素上的
  • 你能够在文档加载完之前衔接事宜处置惩罚函数,如许能够协助你更好地利用你能够没有用的时刻

瑕玷:

  • 这个要领在Jquery 1.7今后的版本被弃用了,你应当在你的代码里逐渐摒弃运用它
  • 运用这个要领时链式操纵没有获得准确的支撑,能够会涌现某些毛病
  • 所做的婚配操纵基本上没用由于它只用于在document元素上注册事宜处置惩罚函数
  • 运用 event.stopPropogation() 要领将会没用,由于事宜老是已被托付到了document元素上
  • 由于一切的挑选器或许事宜信息都被附加到document元素上了,所以一旦有一个事宜要挪用某个事宜处置惩罚函数,Jquery会在一大堆贮存的元数据中运用matchesSelector要领来决议哪个事宜处置惩罚函数将会被挪用,假如这个函数有的话。
  • 由于你所衔接的事宜老是被托付到document上,所假如你的DOM的层级很深的话,这会致使肯定的机能题目

运用Delegate要领

.delegate()要领与.live()体式格局完成体式格局相相似,它不是将挑选器或许事宜信息附加到document,而是让你指定附加的元素。就像是.live()要领一样,这个要领运用事宜托付来准确地事变。

假如你跳过了前面关于 .live() 要领的引见,你能够要归去从新看看它,由于这里涉及到之前我所论述的一些内部逻辑

/* .delegate() 要领会将挑选器和事宜信息 ( "li a" & "click" ) 附加到你指定的元素上 ( "#members" )。
*/

$( "#members" ).delegate( "li a", "click", function( e ) {} );

.delegate()要领非常壮大。在上面这个例子中,与事宜处置惩罚函数关联的挑选器和事宜信息将会被附加到( #members” )这个元素上。如许做比运用.live()高效多了,由于.live()要领老是将与事宜处置惩罚函数关联的挑选器和事宜信息附加到document元素上。别的,运用.delegate()要领处理很多其他题目。请参阅下方列出的详细信息。

长处:

  • 你能够挑选将挑选器或许事宜信息附加到指定的元素。
  • 婚配操纵现实上在前面并没有实行,而是用来注册到指定的元素。
  • 链式操纵能够获得准确的支撑
  • Jquery依然须要迭代这些挑选器或许事宜信息来婚配元素,不过由于你能够挑选哪个元素作为根元素,所以挑选的量会大幅削减
  • 由于这项手艺运用了事宜托付机制,它能够婚配到被动态地增加到DOM的元素
  • 你能够在文档加载完之前衔接事宜处置惩罚函数

瑕玷:

  • .bind()要领不能够直接升级到.delegate()要领
  • Jquery依然须要运用marchesSelector要领在附加到指定根元素的挑选器或许事宜信息中挑选决议哪个事宜处置惩罚函数会被挪用。但是,附加到指定根元素的元数据会比运用.live()要领的时刻要小得多。
  • 当操纵大批婚配的元素时会有机能方面的题目
  • 附加操纵是在前期完成的,这能够致使页面加载时存在机能题目

运用On要领

你知道吗,在Jquery 1.7版本中.bind().live().delegate()要领只须要运用.on()要领一种体式格局来挪用它们。固然.unbind().die().undelegate()要领也一样。一下代码片断是从Jquery 1.7版本的源码中截取出来的


bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
unbind: function( types, fn ) {
    return this.off( types, null, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
die: function( types, fn ) {
    jQuery( this.context ).off( types, this.selector || "**", fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},
undelegate: function( selector, types, fn ) {
    return arguments.length == 1 ? 
        this.off( selector, "**" ) : 
        this.off( types, selector, fn );
}

考虑到这一点,运用.on()要领看起来像以下体式格局一样…


/* Jquery的 .bind() , .live() 和 .delegate() 要领只须要运用`.on()`要领一种体式格局来挪用它们 */

// Bind
$( "#members li a" ).on( "click", function( e ) {} ); 
$( "#members li a" ).bind( "click", function( e ) {} ); 

// Live
$( document ).on( "click", "#members li a", function( e ) {} ); 
$( "#members li a" ).live( "click", function( e ) {} );

// Delegate
$( "#members" ).on( "click", "li a", function( e ) {} ); 
$( "#members" ).delegate( "li a", "click", function( e ) {} );

你能够注重到了,我怎样运用.on()要领决议了它怎样挪用其他要领。你能够以为.on()要领被具有差别署名的要领”重载“了,而这些要领完成了差别的事宜绑定的衔接体式格局。.on()要领的涌现为API带来了很多方面的一致性,并愿望让事变变得不那末杂沓。

长处:

  • 使种种事宜绑定要领一致。
  • 由于在Jquery源码中.bind().live().delegate()要领现实上是挪用了此要领,因而简化了jQuery代码库并删除了一级重定向。
  • 这类体式格局依然供应了运用.delegate()要领的长处,而且依然供应对.bind()要领的支撑,假如你须要的话。

瑕玷:

  • 给人带来了一些疑惑,由于要领的现实实行体式格局将依据你怎样挪用要领而转变。

总结

假如你对差别的绑定事宜要领有所疑惑,那末不要忧郁,由于API生长了一段时刻了,有很多前人的履历能够自创。也有很多人将这些要领视为魔法,不过一旦你相识了他们事变背地的道理,将协助您相识怎样更好地处置惩罚项目。
以下是这篇文章的英华地点…

  • 运用.bind()要领异常糟蹋机能由于它把同一个事宜处置惩罚函数附加到了每个婚配的元素上
  • 你应当停止运用.live()要领由于它被弃用了同时也会带来很多题目
  • 运用.delegate()要领会给你带来很多优点当你须要处理一些机能上的题目和对动态增加的元素作出处置惩罚
  • 新的.on()要领实在就是模仿.bind().live().delegate()完成的语法糖,详细取决于你怎样挪用它
  • 新的方向是运用新的.on()要领。先熟习语法,并最先在你的一切的Jquery 1.7版本以上的项目运用它吧!

关于上面枚举的长处或许瑕玷,你有新的补充吗?你近来最先运用.delegate()要领了吗?你对新的.on()要领怎么看呢?把你的主意写到用批评告诉我吧!感谢!

第一次翻译,文章中能够会涌现一些不通畅的处所,愿望获得人人的明白,毕竟我照样个门生啊!

原文链接

    原文作者:could
    原文地址: https://segmentfault.com/a/1190000010435530
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞