事件机制

事件机制之冒泡、传播、委托

DOM事件流(event flow)存在三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段

事件捕获阶段(event capuring)

通俗理解就是,当鼠标点击或触发dom事件时,浏览器会从根节点由外往内进行事件传播,即点击了子元素,如果父元素通过事件捕获注册了对应的事件的话,会先触发父元素绑定的的事件。

事件冒泡(dubbed bubbling)

与事件捕获相反,事件冒泡是从目标元素由内往外进行事件传播,直到根节点。

无论是事件冒泡还是事件捕获,都有一个共同点就是事件传播,她就像一根引线,只有通过引线才能将绑在引线上的鞭炮(事件监听器)引爆,试想一下,如果引线不导火了,那鞭炮就只有一响了!

dom事件标准事件流的触发先后顺序是:先捕获后冒泡,即当触发dom事件时,会进行事件捕获,捕获到事件源后通过事件传播进行事件冒泡。不同浏览器对此有不同的实现,IE10及以下不支持捕获型事件,所以就少了一个时间捕获阶段,IE11,Chrome,Firefox,Safari等浏览器则同时存在。

事件绑定的方法
addEventlistener(event,listener,useCapture)

参数定义:event——(事件名称:如click,不带on)

listener——事件监听函数,

useCapture——是否采用事件捕获进行事件捕获,默认为false,即采用事件冒泡方式。

addEventListener在IE11,Chrome,Firefox,Safari等浏览器都得到支持。

attachEvent(event,listener)

参数定义:event—(事件名称,如onclick,带on),

listener—事件监听函数。

attachEvent主要用于IE浏览器,并且仅在IE10及以下才支持,IE11已经废了这个方法了

事件冒泡例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
#parent{width:200px;height:200px;background:yellow;margin:10px auto;border:1px solid black;}
#children{width:50px;height:50px;background:pink;margin:80px auto;}
</style>
<title>Document</title>
</head>
<body>
<div id="parent">
<div id="children"></div>
</div>
</body>
</html>
<script>
var children = document.getElementById('children');
var parent = document.getElementById('parent');
document.body.addEventListener('click',function(){console.log('body')},false);
parent.addEventListener('click',function(){console.log('parent')},false);
children.addEventListener('click',function(){console.log('children');
//event.stopProparation;
//可停止事件传播},false);
</script>

当点击子盒子时,打印结果依次为children——parent——body

事件触发的顺序是由内到外的,这就是事件冒泡,虽然只点击了子元素,但是他的父元素也会触发相应的事件,其实这也是合理的,因为父元素里面,点击了子元素不就相当于变相的点击了父元素。

若不想触发父元素可停止事件传播只需在子元素中添加event.stopProparation;即可。

事件捕获例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
body{background: green;}
#parent{width:200px;height:200px;background:yellow;margin:10px auto;border:1px solid black;}
#children{width:50px;height:50px;background:pink;margin:80px auto;}
</style>
<title>Document</title>
</head>
<body>
<div id="parent">
<div id="children"></div>
</div>
</body>
</html>
<script>
var children = document.getElementById('children');
var parent = document.getElementById('parent');
document.body.addEventListener('click',function(){console.log('body')},true);
parent.addEventListener('click',function(){console.log('parent')},true);
children.addEventListener('click',function(){console.log('children')},true);
</script>

点击children方块,打印body——parent——childre

点击parent方块,打印body——parent

点击body区域,打印body

事件通过事件捕获的方式注册了click事件,所以在事件捕获阶段就会触发,先是触发最外围注册了事件捕获的body,而后触发事件捕获的parent,最后触发事件源。这就是事件的时间流程。

文章目录
  1. 1. 事件机制之冒泡、传播、委托
    1. 1.0.0.1. 事件捕获阶段(event capuring)
    2. 1.0.0.2. 事件冒泡(dubbed bubbling)
    3. 1.0.0.3. 事件绑定的方法
      1. 1.0.0.3.1. addEventlistener(event,listener,useCapture)
      2. 1.0.0.3.2. attachEvent(event,listener)
      3. 1.0.0.3.3. 事件冒泡例子
      4. 1.0.0.3.4. 事件捕获例子
|