在所有的现代浏览器当中——除了IE9之前的版本——都实现了DOM2标准事件模型,这个事件模型规定:每一个DOM元素所触发的事件都要经历三个阶段:一、捕获阶段;二、目标对象本身的事件处理程序调用阶段;三、冒泡阶段。

冒泡阶段:当文档元素上发生某个类型的事件时,他们会在文档树上向上传播。(即调用父元素的相同类型的事件处理函数)

捕获阶段:捕获阶段像反向的冒泡阶段。最先调用Window对象的捕获处理程序,然后是Document对象的捕获处理程序,接着是body对象的,再然后是DOM树向下,以此类推,直到调用事件目标元素的父元素的捕获事件处理程序。在目标元素对象本身上注册的捕获事件处理程序不会被调用。

在DOM2标准事件模型中,为一个DOM元素绑定事件的方法为addEventListener(),这个方法要求传递三个参数,第一个参数为一个字符串,表示事件的类型,如"click";第二个参数是一个函数,表示事件处理程序,浏览器会默认为该函数传递一个事件对象(Event);第三个参数是一个布尔值,布尔值为false表示此函数将注册为冒泡事件处理程序(通常设置为false即可),如果值为true,表示此函数将注册为捕获事件处理程序。值得注意的是,能通过多次调用addEventListener()为同一个对象注册同一事件类型的多个处理程序函数。当对象上发生事件时,所有该事件类型的注册处理程序都会按照注册的顺序调用。

分析事件的触发过程,分两种情况:

1.当目标元素不存在父元素或目标元素的父元素并没有注册与触发目标元素相同类型的事件时,事件模型的第一和第三阶段是没有实际意义的(即不会发生任何的事情)。

2.当目标元素存在父元素且目标元素的父元素注册了与触发目标元素相同类型的事件时,事件模型的第一和第三阶段就开始起作用了:

为了方便,先将以下示例中页面效果截图如下,所有示例的页面效果都是如此:

html中页面效果

html:

<div id="eventSpreadDiv" style="padding:20px;background-color:red;width:300px;">
<button id="eventSpreadBtn" type="button">eventSpreadBtn</button>&nbsp;&nbsp;&nbsp;eventSpreadDiv
</div>

(1) 父元素注册捕获事件,子元素不注册事件:

js:

document.getElementById("eventSpreadDiv").addEventListener("click", function(e) {console.log(e.currentTarget.id);}, true);

控制台输出:

点击div(红色区域):

eventSpreadDiv

点击button:

eventSpreadDiv

分析:当点击div时,出现的是事件触发过程的情况1:目标元素不存在父元素,所以只执行了注册在eventSpreadDiv上的click方法,此时e.currentTarget就是eventSpreadDiv;当点击button时,出现的是事件触发过程的情况2:目标元素(此时是button)的父元素(div)注册了与触发目标元素相同类型的事件(click事件),又因为div上注册的click事件的类型为捕获事件,所以当事件模型进行第一阶段时,先执行了div的click事件,此时e.currentTarget就是eventSpreadDiv;然后执行第二阶段,即目标元素button的click事件(并无注册事件);接下来是第三阶段冒泡阶段(也没有相应的函数调用)。

(2)父元素注册冒泡事件,子元素不注册事件

js:

document.getElementById("eventSpreadDiv").addEventListener("click", function(e) {console.log(e.currentTarget.id);}, false);

控制台输出:

点击div(红色区域):

eventSpreadDiv

点击button:

eventSpreadDiv

分析:当点击div时,出现的是事件触发过程的情况1:目标元素不存在父元素,所以只执行了注册在eventSpreadDiv上的click方法,此时e.currentTarget就是eventSpreadDiv;当点击button时,出现的是事件触发过程的情况2:目标元素(此时是button)的父元素(div)注册了与触发目标元素相同类型的事件(click事件),又因为div上注册的click事件的类型为冒泡事件,所以事件模型进行第一阶段时没有相应的函数调用;然后执行第二阶段,即目标元素button的click事件(并无注册事件);接下来是第三阶段冒泡阶段,此时执行了div的click事件,e.currentTarget就是eventSpreadDiv。

(3)父元素注册捕获事件和冒泡事件,子元素注册click事件

js:

document.getElementById("eventSpreadBtn").addEventListener("click", function(e){console.log(e.currentTarget.id)}, false);
document.getElementById("eventSpreadDiv").addEventListener("click", function(e) {console.log("冒泡" + e.currentTarget.id);}, false);
document.getElementById("eventSpreadDiv").addEventListener("click", function(e) {console.log("捕获" + e.currentTarget.id);}, true);

控制台输出:

点击div(红色区域):

冒泡eventSpreadDiv
捕获eventSpreadDiv

点击button:

捕获eventSpreadDiv
eventSpreadBtn
冒泡eventSpreadDiv

分析:当点击div时,出现的是事件触发过程的情况1:目标元素不存在父元素,所以只执行了注册在eventSpreadDiv上的click方法,但是,此时div被注册了两个click方法,所以,click事件其实被触发了两次,调用顺序为代码的注册顺序(即先调用第一个被注册的冒泡事件再调用第二个被注册的捕获事件),这两个事件执行时的e.currentTarget都是div;当点击button时,出现的是事件触发过程的情况2:目标元素(此时是button)的父元素(div)注册了与触发目标元素相同类型的事件(click事件),又因为div上既注册了事件类型为click的捕获事件,又注册了事件类型为click的冒泡事件,所以当事件模型进行第一阶段时,执行了div的click捕获事件,此时e.currentTarget就是eventSpreadDiv;然后执行第二阶段,即目标元素button的click事件,此时e.currentTarget就是button;接下来是第三阶段冒泡阶段,执行了div的click冒泡事件,此时e.currentTarget就是eventSpreadDiv。

总结:DOM2标准事件模型,为我们编写JavaScript事件驱动型的程序提供了更灵活的方案,比如我们可以在捕获阶段和冒泡阶段来阻止事件的继续传播(详情请看上一篇),也可利用这一模型进行代码的调试。

本文出自 “希望家园” 博客,转载请与作者联系!

JavaScript中的事件传播(DOM2标准事件模型)相关推荐

  1. JavaScript基础14-day16【事件委派、事件绑定、事件传播、滚轮事件、键盘事件、键盘移动div】

    学习地址: 谷粒学院--尚硅谷 哔哩哔哩网站--尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) JavaScript基础.高级学习笔记汇总表[尚硅谷最新版Ja ...

  2. JavaScript中的BOM操作的常见事件

    BOM操作的常见事件 1.点击事件clcik onclcik绑定点击 标签ID.onclick = function(){ 程序: } 示例1. d1.onclick = function(){ co ...

  3. 【20190226】JavaScript-知识点记录:dom0级事件,dom2级事件

    DOM0级事件处理程序: 通过将元素的事件处理程序属性(如onclick)的值设置为一个函数来指定事件处理程序的方法称为DOM0级方法,它被认为是元素的方法,这时候的事件处理程序是在元素的作用域中运行 ...

  4. JavaScript中 onclick()、click()触发点击事件的区别

    function load(){ //下面两种方法效果是一样的document.getElementById("target").onclick();document.getEle ...

  5. 理解JavaScript中的事件

    在很多语言的学习中,"事件"都是一个比较难理解,但是又是一个很重要的概念.JavaScript中的事件处理也是一样,正因为有了事件处理,才会出现Ajax拖动的效果.本文就讨论一下J ...

  6. JavaScript中的事件处理程序

    JavaScript和HTML之间的交互是通过事件实现的.事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间.可以使用事件处理程序来预订事件,以便在事件发生的时候执行响应的代码.这种观察者模式的模 ...

  7. javaScript事件(二)事件处理程序

    一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 前面提到,事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字.响应 ...

  8. 关于DOM2级事件的事件捕获和事件冒泡

    DOM2级事件中addEventListener的执行机制,多个addEventListener同时添加时的执行先后规律: W3C的DOM事件触发分为三个阶段: ①.事件捕获阶段,即由最顶层元素(一般 ...

  9. JavaScript系列学习笔记 —— 冒泡型和捕捉型事件

    目录 一.事件模型 1.1 冒泡型事件(Bubbling) 1.2 捕获型事件(Capturing) 1.3 DOM标准事件模型 二.事件对象 三.注册与移除事件监听器 1.IE下注册监听器与移除监听 ...

最新文章

  1. Ubuntu 打开文件 (使用nautilus )
  2. 解决Android Studio由于版本问题不识别import android.support.v7.app.AppCompatActivity;
  3. mysql mac 环境变量配置_mac安装mysql数据库及配置环境变量
  4. unity项目中使用BUGLY遇到的的几个问题
  5. SDNU 1194.传纸条(DP) 1032.机器人
  6. Bootstrap组件_输入框组
  7. 爱思助手短信备份到安卓_爱思助手肿么将短信导入iphone
  8. java中常见的几种内部类,你会几个?(未完)
  9. java输出1-100内的所有5的倍数,5个一行
  10. ubuntu安装kali工具包
  11. ubuntu安装 rust nightly_一起学Rust编程「1」:开发环境
  12. 关于商业计划书(Business Project,以下简称BP)写作那些事儿(一)
  13. Unity 实现部分模型流光效果
  14. 数据科学家成长指南(上)
  15. PGP实现邮件加密和签名
  16. 上海电力学院计算机组成与结构试卷,数据结构
  17. introduce page
  18. Objective-C面向对象
  19. 安全模式删除入网小助手_入网小助手 监控
  20. 算法——机器学习——无监督学习—— K均值(K-means)图解动画

热门文章

  1. 拿shell的一些方式
  2. c++IO流——开工啦
  3. Python实现连接Mysql数据库实现增删改查
  4. 基于Vue的极简生成器 — Vuepress
  5. 苹果手机怎么找回删除的照片?三种最全面的照片恢复方法
  6. 一文解决,WPS编辑word文档时,批注的解决按钮灰色无法点击
  7. android auto 字体大小,TextView自动调整字体大小
  8. 测试点击屏幕次数的软件_最新5G测试软件FAT详细介绍(包含锁频锁网锁PCI、信令/事件查看等功能)...
  9. 为什么电脑会python下载失败_为什么python安装失败怎么解决
  10. 最佳配色网站_最佳学生网站2013