jQuery事件绑定bind、live、delegate和on的区别

最近写项目页面用了不少jQuery的东西,过程当中对jQuery的事件绑定方法有些疑惑,经过学习各种资料,现在终于明白不少。恰巧有同学和我有一样的疑惑,我正好梳理一下思路,写下本文。如果你也对jQuery中眼花缭乱的事件绑定方法不太明白的话,你来对地方了。

继续阅读前,我认为你需要先知道以下几点基础知识:DOM对象是树形结构的,DOM中的事件会从触发事件的目标节点开始逐级向上冒泡。

每当我们想给某个元素绑定事件的时候,第一个想到的方法是bind,我们就先来说说bind。bind的作用是给具体的某个元素绑定事件,比如:

    $('button').bind('click', function () { });

给所有的button元素添加了点击事件处理方法。这似乎已经可以完成大部分的事件绑定任务了,然而有一个问题它无法解决–如果某一元素是新添加的怎么办?bind将事件处理函数绑定在了具体的元素上,而新添加的元素身上是没有被绑定处理函数的。也就是说,如果执行完上面的代码后再动态添加一个button元素,新添加的这个button元素是没有被绑定事件处理函数的。

于是,live出现了。对于刚开始接触jquery的人来说,live是一个很神奇的事件绑定方法,无论某一元素已经存在还是将来会被添加到页面中,live都能将事件绑定到它身上。

真的很神奇吗?其实它的原理很简单,那就是“事件委派”。什么是事件委派?举个简单的例子。

假如有一个表格,我们要动态增删里面的行元素,同时想给每一个行元素绑定一个点击事件。给具体的tr元素绑定事件是不现实的,因为它们总是不断变化的。于是我们可以换个思路,为什么一定要给tr元素绑定事件呢?

我们可以把事件绑定到table元素上,发生在table的子元素身上的点击事件都会冒泡到table元素上,在这里可以做一个比较,如果点击事件的目标是tr元素,执行绑定的函数就好了。这就是事件委派,委派某个元素处理子元素触发的事件。

    $('table tr').live('click', function () { });

这样,就可以给tr元素绑定点击事件,无论它是已经存在的,还是将来被添加的。那么,执行完上面的代码,事件确实被绑定在table元素上了吗?不!

现实中,我们要动态添加的元素指不定在dom树的哪一层。为了让所有新添加的元素都能触发预先绑定的事件处理函数,jquery将事件处理函数委派在了dom树的根元素,也就是document元素,身上。这样一来,无论新添加的元素位于dom树的哪个层级,它触发的事件总会冒泡到根元素上。在这里,可以做一个判断,如果事件触发目标是想要绑定事件处理函数的那个元素,执行该函数就好了。

这看起来很美好,似乎我们完全可以放弃bind,在任何情况下都可以使用live了。不过,等等,如果真是这样的话,后边的delegate就没有用武之地了。

live方法的好处不言而喻,然而它也有弊端。假设我们还是要给tr元素绑定点击事件。如果页面中有一千个元素,只有10个是tr元素,会是什么情况?那990个不相干的元素触发的事件也会冒泡到根元素上,在那里做一次比较,无形当中就会带来性能的消耗。这可真是宁可错杀一千,也不放过一个啊。显然,live并没有看上去的那么美好,于是delegate闪亮全场了。

我们要给tr元素绑定事件,离它最近的父元素就是table了。既然如此,我们为什么还要不辞辛苦地把事件绑定在document元素上,而不是绑在table身上呢?delegate就是干这个活的。

    $('table').delegate('tr', 'click', function () { });

上面的代码将点击事件委派在table元素上,其下的tr元素身上的点击事件会触发处理函数。到目前为此,我们认识了三个和事件绑定有关的方法。他们的使用方法和使用时机你都记住了吗?好吧,我是费了点功夫才记住并区分它们的。

绑定事件居然有三个方法,太可怕了,要是只有一个就好了。其实,jquery的作者也是这么想的。从1.7版本开始,jquery添加了一个新的事件绑定方法–on–来代替之前提到的所有方法。这真是一个令人欣喜的消息。on的使用方法很简单,如果你没有指定后代元素,那么就是简单的事件绑定,类似于bind。比如:

    $('tr').on('click', function () { });

会把点击事件绑定在tr身上,如果执行完代码后新添加了一个tr元素,那它身上自然是没有事件处理函数的。那怎么做事件委派呢?是这个样子的:

    $('table').on('click', 'tr', function () { });

事件委派到了table元素身上,它的tr子元素身上的点击事件会触发事件处理函数。

好了,从今天起,忘掉bind、live和delegate吧,on才是你居家旅行,必备的神器!据说,只是据说,在新版本中,就算你调用bind、live或delegate,它内部都会调用on。既然如此,我们为什么不自己使用on呢?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值