资讯专栏INFORMATION COLUMN

深入理解js Dom事件机制(一)——事件流

OBKoro1 / 1840人阅读

摘要:事件捕获提出的事件流模型称为事件捕获。事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。

首先我们思考一个很有意思的事情:一张纸上画了两个同心圆,当我们把手指放到圆心上时,手指指向的不是一个圆,而是纸上的两个圆,同理之,当我们单击网页上的一个div块的时候(代码片段一),单击事件会仅仅作用在这个div上面吗? 在浏览器发展到第四代时,IE和Netscape的开发团队都遇到这个问题,他们都一致认为,除了单击div块,我们也单击了body、 html、甚至是整个document,但不幸的是两个团队针对事件流模型产生了两个完全相反的概念。

代码片段一:




    
    事件流


    
Click me
1. 事件冒泡(推荐)

IE的事件流称为事件冒泡。
即:事件由最具体的元素接收(div),逐级向上传播到不具体的节点(document)。

当我们点击代码片段一中id为box的div块时,单击事件会按照如下顺序传播:
div ——> body——> html ——> document

如上图所示,click首先在div元素上发生,然后沿着Dom树向上传播,每一级节点都会发生直至传播到document对象。

测试代码




    
    事件流



    

测试效果:

note: 几乎现代所有的浏览器都支持事件冒泡,不过有一些细微的差别
IE5.5 和 IE5.5 - 版本的事件冒泡会跳过html元素(body 直接到 document)
IE9、Firefox、Chrome、Safari则一直冒泡到window对象。

2、事件捕获

Netscape提出的事件流模型称为事件捕获。
即:事件从最不具体的节点开始接收(document),传递至最具体的节点

,和IE的冒泡刚好相反, 事件捕获的本意是当事件到达预定目标前捕获它。

当我们点击代码片段一中id为box的div块时,单击事件会按照如下顺序传播:
document——> html ——> body ——> div

note: 虽然事件捕获是Netscape唯一支持的事件流模型,但IE9、Firefox、Chrome、Safari目前也都支持这种事件模型,由于老版本的浏览器并不支持,所以我们应该尽量使用事件冒泡,有特殊需求的时候再考虑事件捕获。

3、DOM2级事件流

为了能够兼容上述两种事件模型,又提出了一个DOM2级事件模型,它规定了事件流包含三个阶段:

事件捕获阶段:为事件捕获提供机会;

处于目标阶段:事件的目标接收到事件(但并不会做出响应);

事件冒泡阶段:事件响应阶段;

在DOM2级事件流中,但我们点击代码片段一中的div,在事件捕获阶段从document ->html ->body就停止了(div元素在这个阶段并不会接收到点击事件)。紧接着,事件在div上发生,并把事件真正的处理看成是冒泡阶段的一部分,然后,冒泡阶段发生,事件又回传到document。

测试代码:




    
    DOM2级事件流



    

测试结果

4、事件流的典型应用——事件代理

传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。

事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理, 下面举例说明:

传统的事件会为每个dom添加事件,代码如下:





    
    传统的事件绑定



    
  • red
  • orange
  • yellow
  • green
  • blue
  • indigo
  • purple

事件代理的处理方式如下:





    
    传统的事件绑定



    
  • red
  • orange
  • yellow
  • green
  • blue
  • indigo
  • purple

使用事件代理的好处:

将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。

DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。

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

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

相关文章

  • 深入理解js Dom事件机制(二)——添加事件处理程序

    摘要:深入理解事件机制一事件流事件就是当用户或者浏览器自身执行的某种动作,诸如等都是事件的名称,那响应个事件的函数就称为事件处理程序事件处理函数事件句柄。 深入理解js Dom事件机制(一)——事件流 事件就是当用户或者浏览器自身执行的某种动作,诸如 click、mouseover等都是事件的名称,那响应个事件的函数就称为事件处理程序(事件处理函数、事件句柄)。 事件处理程序的名字都是以on...

    ddongjian0000 评论0 收藏0
  • 深入理解js Dom事件机制(二)——添加事件处理程序

    摘要:深入理解事件机制一事件流事件就是当用户或者浏览器自身执行的某种动作,诸如等都是事件的名称,那响应个事件的函数就称为事件处理程序事件处理函数事件句柄。 深入理解js Dom事件机制(一)——事件流 事件就是当用户或者浏览器自身执行的某种动作,诸如 click、mouseover等都是事件的名称,那响应个事件的函数就称为事件处理程序(事件处理函数、事件句柄)。 事件处理程序的名字都是以on...

    qianfeng 评论0 收藏0
  • javascript:深入理解事件

    摘要:所有节点中都包含这两个方法,并且它们都接收个参数要处理的事件名作为事件处理程序的函数和一个布尔值。当这个布尔值为时,表示在捕获阶段调用事件处理程序若果是,表示在冒泡阶段调用事件处理程序。 事件流 定义: 1.事件流描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。 2.事件就是用户或浏览器自身执行的某种动作。诸如click(点击)、load(加载)、mouseover(...

    Null 评论0 收藏0
  • 【Step-By-Step】周面试题深入解析 / 周刊 03

    摘要:禁止内联脚本执行规则较严格,目前发现使用。合理使用上报可以及时发现,利于尽快修复问题。因为事件会从目标元素一层层冒泡至对象。允许给一个事件注册多个监听。表示在捕获阶段触发,表示在冒泡阶段触发。 关于【Step-By-Step】 Step-By-Step (点击进入项目) 是我于 2019-05-20 开始的一个项目,每个工作日发布一道面试题。每个周末我会仔细阅读大家的答案,整理最一份...

    hedge_hog 评论0 收藏0

发表评论

0条评论

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