Js-事件分发与DOM事件流
原文地址:https://www.jianshu.com/p/dc1520327022
Js事件分发与DOM事件流
对JavaScript分发事件不熟悉,网上查阅相关资料整理后,记录一下对Javascript事件分发机制相关的知识。
当触发某个事件时会相应生成一个事件对象,而这个事件对象则会根据DOM事件流的方向进传递,看下图:
图片来源:http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
事件对象会随着DOM事件流从Window依次向下,最终传递给事件目标。但是在这个过程开始之前,事件对象的传递路径需要先被确定下来。
这个传递路径是一个有序的列表,里面包含了传递到事件目标需要经过的节点。而传递路径反映了文档的树结构。列表里面的最后一项就是事件目标,列表里面先于它的项指向目标的祖先节点,它的上一项指向目标的父节点。
比如上图由Window->Document->html->body->table->tr->td。一旦传递路径被确定了,事件对象就可以经历一个或者多个事件阶段。通常有三个阶段:捕获阶段,目标阶段,冒泡阶段。某些阶段可能会被跳过,如果浏览器不支持,或者事件对象的传播被停止了。例如,如果把cancelBubble设置为true,冒泡阶段将会被跳过,或者stopPropagation()方法在传递之前就被调用的话,之后所有的阶段都会被跳过。
- 捕获阶段:事件对象从目标的祖先节点Window开始传播直至目标。
- 目标阶段:事件对象传递到事件目标。如果事件的type属性表明后面不会进行冒泡操作,那么事件到此就结束了。
- 冒泡阶段:事件对象以一个相反的方向进行传递,从目标开始,到Window对象结束。
直接上代码,写了三个嵌套的div:
<!DOCTYPE >
<html>
<head lang="en">
<title></title>
<meta charset="UTF-8">
<style type="text/css">
#parent { width: 300px; height: 300px;padding:10px;background:lightyellow;}
#child { width: 200px; height: 200px; background: lightblue; }
#grandchild { width: 100px; height: 100px; background: lightcoral; }
</style>
</head>
<body>
<div id="parent">
parent
<div id="child">
child
<div id="grandchild">
grandchild
</div>
</div>
</div> <script type="text/javascript">
window.alert = function (msg) {
console.log(msg);
};
var parent= document.getElementById('parent'),
child = document.getElementById('child'),
grandchild = document.getElementById('grandchild'); parent.addEventListener('click', function (e) {
alert('父节点冒泡')
}, false);
parent.addEventListener('click', function (e) {
alert('父节点捕获')
}, true);
child.addEventListener('click', function (e) {
alert('子节点捕获')
}, true);
child.addEventListener('click', function (e) {
alert('子节点冒泡')
}, false);
grandchild.addEventListener('click', function (e) {
alert('孙子节点冒泡')
}, false);
grandchild.addEventListener('click', function (e) {
alert('孙子节点捕获')
}, true); </script>
</body>
</html>
当点击了parent时,依次打印:父节点冒泡,父节点捕获。
当点击了child时,依次打印:父节点捕获,子节点捕获,子节点冒泡,父节点冒泡。
当点击了grandchild时,依次打印:父节点捕获,子节点捕获,孙子节点冒泡,孙子节点捕获,子节点冒泡,父节点冒泡。
由此可以得出来结论,点击了目标节点后,捕获阶段里事件会从外向目标传递;到了目标阶段,捕获和冒泡的执行顺序按照事件被定义的先后顺序执行;最后冒泡阶段,又会由目标向外进行传递。
补充说明事件中stopPropagation与stopImmediatePropagation区别:
两都都可以阻止事件的进一步捕获或冒泡,但后者同时可以阻止任何事件处理程序被调用,包括目标阶段的事件。
比如修改上面代码里面子节点的目标事件:
child.addEventListener('click', function (e) {
alert('子节点捕获')
}, true);
child.addEventListener('click', function (e) {
e.stopPropagation();
// e.stopImmediatePropagation();
alert('子节点捕获2')
}, true);
child.addEventListener('click', function (e) {
alert('子节点冒泡')
}, false);
使用stopPropagation():点击子节点,依次打印:父节点捕获,子节点捕获,子节点捕获2,子节点冒泡。
使用stopImmediatePropagation():点击子节点,依次打印:父节点捕获,子节点捕获,子节点捕获2。
两者都阻止了事件向父节点进行传播,同时使用stopImmediatePropagation()阻止了事件向目标阶段后面的事件的传播。
参考:
https://www.w3.org/TR/DOM-Level-3-Events/#event-flow
如果您在阅读过程中发现有什么问题,欢迎指正。
Js-事件分发与DOM事件流的更多相关文章
- [DOM Event Learning] Section 4 事件分发和DOM事件流
[DOM Event Learning] Section 4 事件分发和DOM事件流 事件分发机制: event dispatch mechanism. 事件流(event flow)描述了事件对象在 ...
- Js事件分发与DOM事件流
这一篇比较透彻:https://www.jianshu.com/p/dc1520327022 点击了目标节点后,捕获阶段里事件会从外向目标传递:到了目标阶段,捕获和冒泡的执行顺序按照事件被定义的先后顺 ...
- 自定义控件(视图)2期笔记10:自定义视图之View事件分发机制("瀑布流"的案例)
1. Touch事件的传递: 图解Touch事件的传递,如下: 当我们点击子View 02内部的Button控件时候,我们就触发了Touch事件. • 这个Touch事件首先传递给了顶级父View ...
- js事件捕获,事件冒泡,事件委托以及DOM事件流
一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body ...
- DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件
前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...
- cocos2d-x 事件分发机制 ——加速计事件监听
加速计事件监听机制 在上一篇中介绍了cocos2d-x中的触摸事件机制,这篇来介绍下游戏中也常常常使用到的加速计事件,这些都是游戏中的常常要用到的. 移动设备上一个非常重要的输入源是设备的方向.大多数 ...
- cocos2d-x游戏引擎核心(3.x)----事件分发机制之事件从(android,ios,desktop)系统传到cocos2dx的过程浅析
(一) Android平台下: cocos2dx 版本3.2,先导入一个android工程,然后看下AndroidManifest.xml <application android:label= ...
- cocos2d-x 事件分发机制 ——触摸事件监听
cocos2d-x 3.0 出来已经好久了,也已经用3.0写了几个小游戏,感觉3.0的事件触发机制太赞了,随这里总结一下.也算是对知识的一种回顾和加深理解. 3.0的事件分发机制中.须要也只须要通过创 ...
- js和jquery的DOM事件大全
随机推荐
- request-html 登陆百度
import asyncio from requests_html import HTMLSession url = 'https://passport.baidu.com/v2/?login& ...
- Bash基础——减号-
参考:Bash基础——pipe pipe命令在 bash 的连续的处理程序中相当重要.在pipe命令当中,常常会使用到前一个命令的 stdout 作为这次的 stdin , 某些命令需要用到文件名 ( ...
- 【HICP Gauss】数据库 环境的搭建 -1
1.安装规则 1.主机名必须网络唯一 2.主机名必须两位数以上 可以中划线 不能下划线 3.固定IP地址 4.端口号 1888 新增账户 omm 用户组 dbgrp ,家目录 /home/ ...
- java安全相关知识
基本概念 JVM:java虚拟机,Java编译程序将生成Java虚拟机上可运行的目标代码,使得Java程序可以再不同平台不加修改的运行.JVM包含完善的硬件架构,主要分为五大模块-类装载器子系统.运行 ...
- mysql字典取值,列表包含
SELECT * FROM e where JSON_CONTAINS(json_extract(scope_detail, '$.shop'), '001');
- 基于ATtiny85轻松制作一款智能手表
这是基于ATtiny85系列的简约手表系列中的第三款.该款手表通过在微型64x48 OLED显示屏上绘制模拟的手表来显示时间.它使用独立的晶振控制的低功耗RTC芯片来保持每月几秒钟的时间,并在不显示时 ...
- rest-framework认证、权限组件
认证组件: models class User(models.Model): username = models.CharField(max_length=32) password = models. ...
- 一道简单的广搜题:Knight Moves
这本来是要用双向宽度搜索的,但是我用简单的广搜也成功了,L<=300,也不会超时?? 另外一个问题就是,我本来想用原来的代码交,结果80分??将边界条件从小于L改成小于等于L,就对了.我可能不会 ...
- 用python查看网站被百度所有收录网址与标题进行SEO分析
SEO要是和python数据分析联合在一起,可谓是很好的方法,没事的时候尝试写的分析网站被百度收录的网址和标题. 首先得引入两个py模块,分别是:Beautiful Souprequests ...
- LG5325 【模板】Min_25筛
P5325 [模板]Min_25筛 题目背景 模板题,无背景. 题目描述 定义积性函数$f(x)$,且$f(p^k)=p^k(p^k-1)$($p$是一个质数),求 $$\sum_{i=1}^n f( ...