首先,可视化HMTL文档的DOM树是很有帮助的。一个简单的HTML页面如下所示:。
事件冒泡(也称为事件传播)当我们单击链接时,它会触发链接元素的click事件,进而触发我们绑定到元素的click事件的任何函数的执行。复制代码如下: $ ('a ')。bind ('click ',function () {alert('那个图章!'。)})所以点击操作将触发警报功能的执行。
然后,click事件将传播到树的根,传播到父元素,然后传播到每个祖先元素。只要在其后代元素上的click事件被触发,该事件就会被传递给它。
在操作DOM的上下文中,文档是根节点。现在我们可以很容易地解释。bind(),live()和。委托()。的副本代码。bind()如下: $ ('a ')。bind ('click ',function () {alert('那个图章!'。);})这是最简单的绑定方法。JQuery扫描文档以查找所有$ ('a ')元素,并将alert函数绑定到每个元素的click事件。的副本代码。live()如下: $ ('a ')。live ('click ',function () {alert('那个戳!)}) JQuery将alert函数绑定到$(document)元素,并将“click”和“a”作为参数。每当事件在文档节点上冒泡时,它都会检查该事件是否是单击事件,以及该事件的目标元素是否与CSS选择器“a”匹配。如果两者都是,它将执行该函数。live方法也可以绑定到特定的元素(或“上下文”)而不是文档,如下所示:复制代码如下: $ ('a ',$ ('# container') [0])。live ('click ',function () {alert('好痒!) }) .delegate()复制代码如下: $ ('# container ')。委托(' a ',' click ',function () {alert('那个戳!)}) JQuery扫描文档以查找$(“# container”),并使用click事件和CSS选择器“a”作为参数将alert函数绑定到$(“# container”)。每当事件在$(“# container”)上冒泡时,它都会检查该事件是否是click事件,以及该事件的目标元素是否与CSS选择器匹配。如果两次检查的结果都为真,它将执行该函数。请注意,此过程类似于。live(),但它将处理程序绑定到具体元素,而不是文档根。聪明的jser可能会得出这样的结论:$ ('a ')。live ()==$(文档)。代表(' a '),对吗?不,不完全是。为什么?delegate()优于。live()?出于几个原因,人们通常更喜欢jQuery的委托方法,而不是live方法。考虑以下示例:按照如下方式复制代码: $ ('a ')。live ('click ',function(){ blah()});或者$(文档)。委托(' a ',' click ',function(){ blah()});事实上,后者比前者更快,因为前者首先扫描整个文档以找到所有$ ('a ')元素,并将它们保存为jQuery对象。虽然live函数只需要将' a '作为字符串参数传递以供以后判断,但是$()函数并不“知道”链接的方法将是什么。live()。另一方面,委托方法只需要找到并存储$(document)元素。绕过这个问题的一种方法是在$(document)之外调用live bound。ready(),以便立即执行。这样,它将在填充DOM之前运行,因此它不会找到元素或创建jQuery对象。灵活性和连锁能力的活功能也相当令人费解。想想看,它被链接到$ ('a ')对象集,但它实际上作用于$(document)对象。由于这个原因,它可以尝试以一种令人恐惧的方式将方法链接到自身。实际上,我想说的是,以$的形式。直播(' a ',)作为一个全局jQuery方法,live方法会更有意义。最后一点,只支持CSS选择器,live方法有一个非常大的缺点,那就是只能对直接CSS选择器进行操作,非常不灵活。请参阅文章探索jQuery。live()和。有关CSS选择器缺点的更多信息,请参见die()。更新:感谢Hacker News上的踏板和Ellsass在后面的评论中提醒我加入下一部分。为什么选择。live()或。委托()而不是。bind()?毕竟,bind似乎更显而易见,更直接,不是吗?嗯,有两个原因可以解释为什么我们更喜欢委托或者活着来绑定:1。以便将处理程序附加到DOM中可能尚不存在的DOM元素。因为bind直接将处理程序绑定到每个元素,所以它不能将处理程序绑定到页面中尚不存在的元素。2.如果运行$('a ')。绑定(…)然后新的链接通过AJAX添加到页面中,您的绑定处理程序对这些新添加的链接无效。
另一方面,live和delegate绑定到另一个祖先节点,因此它们对当前或将来存在于祖先元素中的任何元素都有效。3.或者为了将处理程序附加到单个元素或一小组元素上,监听后代元素上的事件,而不是循环并将相同的函数逐个附加到DOM中的100个元素上。将处理程序附加到一个(或一小组)祖先元素,而不是直接将处理程序附加到页面中的所有元素,这将带来性能优势。停止传播我想做的最后一个提醒与事件的传播有关。通常,我们可以通过使用这样的事件方法来终止处理函数的执行:复制代码如下: $ ('a ')。bind ('click ',function(e){ e . prevent default()(e . stopper propagation()})。然而,当我们使用live或delegate方法时,处理函数实际上并没有运行。这时,我们的其他处理功能从。bind()已经运行。