资讯专栏INFORMATION COLUMN

细说 jQuery 事件篇(三) - 事件传播

Cc_2011 / 1442人阅读

摘要:是如何决定由哪个元素来处理事件的,以及又是如何优化处理这个问题的,这些都涉及到了事件传播。事件冒泡的弊端事件冒泡可能会导致意料之外的行为,例如在响应事件时,依旧是上例,当为最外层的添加一个事件。使用方法可以避免事件传播导致的问题。

Javascript 是如何决定由哪个元素来处理事件的,以及 jQuery 又是如何优化处理这个问题的,这些都涉及到了事件传播。

事件传播策略

当页面内的发生一个事件时,每个层次的 DOM 元素都有机会来处理这个事件,为了弄懂整个过程,举例说明:


1.事件捕获

有两种策略来处理事件,第一种是事件捕获。
当采取“事件捕获”策略时,点击 a 标签后,事件首先交给外层的元素,然后再往内交给更具体的元素:

div -> span -> a 
2.事件冒泡

另一种策略是“事件冒泡”,事件冒泡与事件捕获刚好相反,当点击 a 标签后,首先会发送到最具体的元素,在这个元素得到响应后,事件会往上冒泡到更外层的元素:

a -> span -> div

一开始,不同的浏览器采用不同的策略来处理事件传播,为了统一化,DOM 标准规定应该同时使用着两种策略,首先通过“事件捕获”来捕获到最具体的元素,接着通过“事件冒泡”返回到 DOM 树的顶层。

3.统一策略

同时,我们很容易理解,对于事件的处理程序既可以发生在事件捕获阶段,也可以发生在事件冒泡阶段,jQuery 为了统一策略决定始终在事件冒泡阶段注册事件处理程序。因此,我们可以假定最具体最内层的元素会首先获得响应事件的机会。

事件冒泡的弊端

事件冒泡可能会导致意料之外的行为,例如在响应 mouseout 事件时,依旧是上例,当为最外层的 div 添加一个 mouseout 事件。此时,如果鼠标移出 div 区域时,肯定会触发 mouseout 事件绑定的程序,这是我们期望的,但是如果鼠标是从 a 元素上离开时,a 元素也会取得一个 mouseout 事件,再通过事件冒泡后,外层的 div 也会获得,这显然不是我们想要的。
div 添加样式来便于区分:

div {
  width: 200px;
  height: 200px;
  background-color: lightblue;
}

绑定 mouseout 事件到 div 上:

  $("div").mouseout(function() { 
    //触发 `alert`
    alert("mouse is out!");
  });

当鼠标从淡蓝色的区域移开时,触发 alert,但是当鼠标放到 a 标签上后再移开,即使没移开 div 区域,同样也会触发 alert,这显然不是我们希望的,这就是事件冒泡带来的弊端。
这里介绍两种直接简单的方法来解决这个问题。

第一是使用 jQuery 自带的 .hover() 方法,.hover() 方法接受两个函数参数,第一个参数在鼠标进入绑定元素时执行,第二个参数在鼠标移除绑定元素时执行。使用 .hover() 方法可以避免事件传播导致的问题。

  $("div").hover(function() {}, function() {
    alert("mouse is out!");
  });

第二种方法是使用 mouseleave 来代替 mouseout 方法。

  $("div").mouseleave(function() {
    //触发 `alert`
    alert("mouse is out!");
  });

这两种方法是针对 mouseout 可能出现的问题来解决的,对于事件冒泡可能导致的其他弊端现象,我们需要用更加适用的方法来解决,因为这个知识点在书中的下一个章节介绍,所以我打算在下一篇博文中总结。

参考

http://book.douban.com/subject/24669823/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78141.html

相关文章

  • 细说 jQuery 事件(四) - 改变事件过程

    摘要:事件对象是一种结构,它会在元素获得处理事件的机会时传递给调用的事件处理程序。事件对象的属性指的是事件目标,它将保存发生事件的目标元素。所以,接下来我们就要想办法改变事件过程来阻止这个行为。 在 《细说 jQuery 事件篇(三) - 事件传播》 中提到了事件冒泡可能造成的弊端,当时举了 mouseout 的例子,对于 mouseout 这个特殊情况,我们可以用 hover 方法来解决,...

    nifhlheimr 评论0 收藏0
  • 细说 jQuery 事件(二) - 处理简单事件

    摘要:我们可以利用可以对用户发起的事件进行处理,这里以样式转换为例来说明。其他类似的操作事件都可以通过这个方法,将处理事件的程序绑定到同名事件上面。 我们可以利用 jQuery 可以对用户发起的事件进行处理,这里以样式转换为例来说明。 增添样式 基于用户的事件,对特定的 DOM 元素样式进行转换是 jQuery 处理事件中比较常见的情形,举例说明,当用户点击输入框后,会增添 highli...

    ckllj 评论0 收藏0
  • 细说 jQuery 事件(五) - 事件的移除和重绑定

    摘要:一种做法是在事件处理程序中使用条件语句进行判断,另一种更彻底的做法就是直接移除该处理程序。事件重绑定我们添加一个按钮,当点击按钮后,所有的事件的处理程序又被重新绑定回来。 如果我们需要移除已经注册的事件处理程序,使某些处理程序失效。一种做法是在事件处理程序中使用条件语句进行判断,另一种更彻底的做法就是直接移除该处理程序。 移除处理程序 假设有个 div 和 button,当我们点击...

    boredream 评论0 收藏0
  • 细说 jQuery 事件(六) - 模拟用户操作

    摘要:查看上方法被触发的原因是但是通过方法直接修改元素的值并不能触发事件,只有当用户真实输入并改变框的内容时才有效。但是假设我们希望能模拟用户的操作,则需要用到方法,修改代码如下此时,不需要用户进行点击操作,通过已经模拟了一次用户的操作。 前阵子在调一个 bug 的时候遇到一个很坑的问题,在判断一个输入框是否有用户输入时触发 updateModel 操作,并向后台发送 PUT 请求,结果调试...

    syoya 评论0 收藏0
  • 细说 jQuery 事件(一) - 代码执行时机

    摘要:在元素一篇介绍过,可以使用来使得代码在加载完毕后自动执行代码,接下来具体介绍下这个机制。这样看上去貌似没什么问题,但是如果有两个函数需要指定时就会遇到麻烦,因为属性只能保存对一个函数的引用,如果我们写成以下形式最后代码执行后的效果是会覆盖。 在元素一篇介绍过,jQuery 可以使用 $(document).ready() 来使得代码在 DOM 加载完毕后自动执行代码,接下来具体介绍下这...

    dunizb 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<