JS事件流模型
JS事件流模型
事件捕获Event Capturing
是一种从上而下的传播方式,以click
事件为例,其会从最外层根节向内传播到达点击的节点,为从最外层节点逐渐向内传播直到目标节点的方式。
事件冒泡Event Bubbling
是一种从下往上的传播方式,同样以click
事件为例,事件最开始由点击的节点,然后逐渐向上传播直至最高层节点。
DOM0级模型
也称为原始事件模型,这种方式较为简单且兼容所有浏览器,但是却将界面与逻辑耦合在一起,可维护性差。
实例
当点击id
为i3
的<div>
时,浏览器会依次弹出2 1 0
。
<!DOCTYPE html>
<html>
<head>
<title>JS事件流模型</title>
</head>
<style type="text/css">
div{
display: flex;
justify-content: center;
align-items: center;
}
</style>
<body>
<div id="i1" style="height: 150px;width: 150px;background: red;" onclick="alert(0)">
<div id="i2" style="height: 100px;width: 100px;background: green;" onclick="alert(1)">
<div id="i3" style="height: 50px;width: 50px;background: blue;" onclick="alert(2)"></div>
</div>
</div>
</body>
</html>
IE事件模型
IE8
及之前的版本是不支持捕获事件的,IE
事件模型共有两个过程:
事件处理阶段target phase
,事件到达目标元素, 触发目标元素的监听事件。
事件冒泡阶段bubbling phase
事件从目标元素冒泡到document
,依次执行经过的节点绑定的事件。
DOM2级模型
DOM2
事件模型是W3C
制定的标准模型,支持捕获型事件和冒泡型事件,调用事件的处理阶段依次为捕获、目标、冒泡。
实例
当点击id
为i3
的<div>
时,浏览器会依次弹出0 1 3 2
,addEventListener
方法的第三个参数为声明绑定的事件为捕获型还是冒泡型,默认为false
,也就是冒泡型。
<!DOCTYPE html>
<html>
<head>
<title>JS事件流模型</title>
</head>
<style type="text/css">
div{
display: flex;
justify-content: center;
align-items: center;
}
</style>
<body>
<div id="i1" style="height: 150px;width: 150px;background: red;">
<div id="i2" style="height: 100px;width: 100px;background: green;">
<div id="i3" style="height: 50px;width: 50px;background: blue;"></div>
</div>
</div>
</body>
<script type="text/javascript">
document.addEventListener('click',(e) => {
alert(0);
},true)
document.getElementById("i1").addEventListener('click',(e) => {
alert(1);
},true)
document.getElementById("i2").addEventListener('click',(e) => {
alert(2);
})
document.getElementById("i3").addEventListener('click',(e) => {
alert(3);
})
</script>
</html>
document
对象与i1
节点绑定的是捕获型的监听事件,i2
与i3
节点绑定的是冒泡型的事件,事件传递的顺序为:
window --- document --- html --- body --- i1 --- i2 --- i3 --- i2 --- i1 --- body --- html --- document --- window
从window
到i3
的过程为捕获阶段,依次执行了过程中绑定的事件,本例中执行了alert(0)
与alert(1)
,然后到达目标阶段的i3
,执行i3
绑定的事件alert(3)
,然后从i3
到window
的阶段为冒泡阶段,执行了绑定的alert(2)
,执行顺序即为0 1 3 2
。
注意
绑定监听事件使用的区别
在DOM0
中直接绑定函数执行时,后定义的函数会覆盖前边绑定的函数,下面这个例子只执行alert(1)
而不执行alert(0)
。click()
是一个对象事件,点击即触发onclick()
绑定的方法,onclick()
是对象的属性,将其绑定函数后即为click()
事件触发后执行的方法。
<!DOCTYPE html>
<html>
<head>
<title>JS事件流模型</title>
</head>
<style type="text/css">
div{
display: flex;
justify-content: center;
align-items: center;
}
</style>
<body>
<div id="i1" style="height: 150px;width: 150px;background: red;"></div>
</body>
<script type="text/javascript">
document.getElementById("i1").onclick = function(){
alert(0);
} // 被覆盖
document.getElementById("i1").onclick = function(){
alert(1);
} // 执行
</script>
</html>
addEventListener
可以为事件绑定多个函数,并且绑定时不需要加on
,其还可以接收第三个参数useCapture
来决定事件时绑定的捕获阶段还是冒泡阶段执行。
document.getElementById("i1").addEventListener('click',(e) => {
alert(0);
}) // 执行
document.getElementById("i1").addEventListener('click',(e) => {
alert(1);
}) // 执行
attachEvent
可以为事件绑定多个函数,绑定时需要加on
,其只支持冒泡阶段执行,所以不存在第三个参数。
document.getElementById("i1").attachEvent('onclick',function(e){
alert(0);
}) // 执行
document.getElementById("i1").attachEvent('onclick',function(e){
alert(1);
}) // 执行
- 学习Spark——那些让你精疲力尽的坑
- 学习Spark——那些让你精疲力尽的坑
- Silverlight 3.0 中的 WriteableBitmap
- WCF后续之旅(10): 通过WCF Extension实现以对象池的方式创建Service Instance
- Silverlight菜单控件 — CurveMenu
- 实力终端撑腰 两枚域名均五位数被秒
- Silverlight制作逐帧动画 v2 - part2
- Nodejs学习笔记(四)--- 与MySQL交互(felixge/node-mysql)
- 学习Spark——环境搭建(Mac版)
- 离线网络环境下一键式部署
- WCF后续之旅(17):通过tcpTracer进行消息的路由
- Linux同步机制(一) - 线程锁
- Silverlight类库介绍-FJCore
- 大型网站的自强之路
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Django+Vue开发生鲜电商平台之2.开发环境搭建
- 安卓计算器
- conda配置清华源
- 头文件保护符
- 对向上转型的理解
- C语言入门系列之12.位运算
- C语言经典习题100例(三)11-15
- Unity 3D自动对焦
- C语言经典习题100例(四)16-20
- C语言经典习题100例(六)26-30
- 再探Numpy中的axis(也是torch中的dim)
- 掌握好这几个css属性,少写100行js代码
- Flash写入性能下降问题
- 如何用开源项目申请 JetBrains 产品的 license
- npm -i 与npm install -S与-D的区别以及dependencies与devDependencies的区别