因为快面试了,打开《JavaScript高级程序设计》,对DOM事件进行整理了下

本文主要解决的问题:

  1. 事件流
  2. DOM事件流的三个阶段

先理解流的概念

在现今的JavaScript中随处可见。比如说React中的单向数据流,Node中的流,又或是今天本文所讲的DOM事件流。都是流的一种生动体现。用术语说流是对输入输出设备的抽象。以程序的角度说,流是具有方向的数据。

事件流分事件冒泡与事件捕获

在浏览器发展的过程中,开发团队遇到了一个问题。那就是页面中的哪一部分拥有特定的事件?

可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上所有的圆。放到实际页面中就是,你点击一个按钮,事实上你还同时点击了按钮所有的父元素。
开发团队的问题就在于,当点击按钮时,是按钮最外层的父元素先收到事件并执行,还是具体元素先收到事件并执行?所以这儿引入了事件流的概念。

通俗说,事件流所描述的就是从页面中接受事件的顺序。

因为有两种观点,所以事件流也有两种,分别是事件冒泡和事件捕获。现主流是事件冒泡。

事件冒泡

事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。

下面写个例子:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event Bubbling</title>
</head>
<body>
<button id="clickMe">Click Me</button>
</body>
</html>

然后,我们给button和它的父元素,加入点击事件。

 var button = document.getElementById('clickMe');

 button.onclick = function() {
console.log('1. You click Button');
};
document.body.onclick = function() {
console.log('2. You click body');
};
document.onclick = function() {
console.log('3. You click document');
};
window.onclick = function() {
console.log('4. You click window');
};

在Chrome浏览器运行:

如果点击了button,那么这个点击事件会按如下的顺序传播

  1. button
  2. body
  3. document
  4. window

也就是说,click事件首先在<button>元素上发生,然后逐级向上传播。

事件捕获

事件捕获的概念,与事件冒泡正好相反。它认为当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。比如说刚才的demo,如果是事件捕获的话,事件发生顺序会是这样的:

  1. window
  2. document
  3. body
  4. button

事件阶段(Event Phases)

当一个DOM事件触发时,它不是在触发的对象上只触发一次的,而是经历三个阶段。分别为

1:一开始从文档的根节点流向目标对象(捕获阶段)

2:然后在目标对向上被触发(目标阶段)

3:之后再回溯到文档的根节点(冒泡阶段).

1. 事件捕获阶段

事件的第一个阶段是捕获阶段。事件从文档的根节点出发,随着DOM树的结构向事件的目标节点流去。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
例如,我把上面的Demo中,window点击事件更改为使用事件捕获模式。(addEventListener最后一个参数,true则代表使用事件捕获模式,false则表示使用事件冒泡模式。不理解的可以去学习一下addEventListener函数的使用)

 window.addEventListener('click', function() {
console.log('4. You click window');
}, true);

此时,点击button的效果是这样的。

可以看到,点击事件先被父元素截获了,且该函数只在事件捕获阶段起作用。

处于目标与事件冒泡阶段

事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。
随后,冒泡阶段发生,事件开始冒泡。

阻止事件冒泡

事件冒泡过程,是可以被阻止的。防止事件冒泡而带来不必要的错误和困扰。
这个方法就是:stopPropagation()
我们对button的click事件做一些改造。

 button.addEventListener('click', function(event) {
// event为事件对象
console.log('1. You click Button');
event.stopPropagation();
console.log('Stop Propagation!');
}, false);

点击后,效果如下图:

不难看出,事件在到达具体元素后,停止了冒泡。但不影响父元素的事件捕获。

总结

事件流:描述的就是从页面中接受事件的顺序。

分有事件冒泡与事件捕获两种。

DOM事件流的三个阶段:

    1. 事件捕获阶段
    2. 处于目标阶段
    3. 事件冒泡阶段

参考资料:《JavaScript高级程序设计》第三版

面试整理之DOM事件阶段的更多相关文章

  1. 整理之DOM事件阶段、冒泡与捕获、事件委托、ie事件和dom模型事件、鼠标事件

    整理之DOM事件阶段 本文主要解决的问题: 事件流 DOM事件流的三个阶段 先理解流的概念 在现今的JavaScript中随处可见.比如说React中的单向数据流,Node中的流,又或是今天本文所讲的 ...

  2. DOM事件阶段以及事件捕获与事件冒泡先后执行顺序

    平时浏览这么多技术文章,如过不去实践.深入弄透它,这个技术点很快就会在脑海里模糊.要加深印象,就得好好过一遍.重要的事情说三遍,重要的知识写一遍. 开发过程中我们都希望使用别人成熟的框架,因为站在巨人 ...

  3. DOM事件

    在慕课网上学习了DOM事件探秘课程,特此整理了一下笔记. 慕课网DOM事件探秘课程地址:http://www.imooc.com/learn/138 事件 是文档或浏览器窗口中发生的特定的交互瞬间.[ ...

  4. 系统学习DOM事件机制

    本文将从以下几个方面介绍DOM事件: 基本概念:DOM事件的级别 DOM事件模型,事件流 描述DOM事件捕获的具体流程 Event对象的常见应用 自定义事件 DOM事件的级别 //DOM0 eleme ...

  5. DOM事件第一弹

    近期温习了部分w3c上关于DOM事件的规范,发现以前有些模糊的概念更加清晰,以及受到罗胖(罗辑思维)的影响,很是想分享自己的了解的东西,希望大家给予指正或补充. 一.事件类型 参数 事件接口 初始化方 ...

  6. DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件

    前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...

  7. Js-事件分发与DOM事件流

    原文地址:https://www.jianshu.com/p/dc1520327022 Js事件分发与DOM事件流 对JavaScript分发事件不熟悉,网上查阅相关资料整理后,记录一下对Javasc ...

  8. 最全的DOM事件笔记

    1. DOM事件模型 DOM是微软和网景发生"浏览器大战"时期留下的产物,后来被"W3C"进行标准化,标准化一代代升级与改进,目前已经推行至第四代,即 leve ...

  9. DOM 事件深入浅出(一)

    在项目开发时,我们时常需要考虑用户在使用产品时产生的各种各样的交互事件,比如鼠标点击事件.敲击键盘事件等.这样的事件行为都是前端DOM事件的组成部分,不同的DOM事件会有不同的触发条件和触发效果.本文 ...

随机推荐

  1. Iterator<转>

    Iterator就是迭代器的意思. Iterator是一个接口,利用迭代器主要是获取元素,很少删除元素.有三个方法:    1)hasNext():判断是否有更多的元素,如果有返回true.    2 ...

  2. 解决在IE中返回JSON格式的数据时提示下载的问题

    如题,以ASP.NET MVC为例,解决办法如下: 控制器中: public JsonResult Test() { return Json(json, "text/html"); ...

  3. Tomcat的目录结构及用途

    目录结构及用途 目录 用途 bin 包含启动/关闭脚本 conf 包含不同的配置文件,包括 server.xml(Tomcat的主要配置文件)和为不同的Tomcat配置的web应用设置缺省值的文件we ...

  4. Debian普通用户添加sudo权限

    转自:http://chenpeng.info/html/964 刚安装好的Debian默认还没有sudo功能.1.安装sudo# apt-get install sudo2.修改 /etc/sudo ...

  5. 图论&数据结构——并查集

    Wikioi 4246 NOIP模拟赛Day2T1 奶牛的身高  题目描述 Description 奶牛们在FJ的养育下茁壮成长.这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的 ...

  6. MYSQL主从数据库搭建

      sc delete "服务名"    删除服务   环境: (以下是我这次搭建所使用的环境) 主数据库: 系统:ubuntu : MYSQL  5.1.63 :ip:192.1 ...

  7. Unity3D开发之NGUI点击事件穿透响应处理

    http://www.xuebuyuan.com/1936292.html 在使用NGUI 开发2D项目的时候,发现了一个问题,就是如果点出一个菜单,然后点击菜单上面的按钮的时候就会使得按钮下面的物品 ...

  8. [BZOJ1789][BZOJ1830][Ahoi2008]Necklace Y型项链

    [BZOJ1789][BZOJ1830][Ahoi2008]Necklace Y型项链 试题描述 欢乐岛上众多新奇的游乐项目让小可可他们玩的非常开心.现在他们正在玩比赛串项链的游戏,谁串的最快就能得到 ...

  9. postgresql 函数demo

    create or replace function refresh_product_usage() returns void as $$ declare rec record; sub_rec re ...

  10. PHP中通过加号合并数组

    通常,我们合并多个数组用的是array_merge()函数,其实,PHP手册中关于数组操作符的介绍给了我们更简单的方法,那就是"+"号,看看下面的例子就明白了(详细了解) 代码: ...