用生命谱写代码的赞歌

0%

事件冒泡与事件捕获

DOM事件

HTML DOM 使 JavaScript 有能力对 HTML 事件做出反应。我们可以在事件发生时执行 JavaScript。

事件冒泡

指从document到触发事件的那个节点,即自下而上的去触发事件,触发顺序自内向外。

绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。true,事件捕获;false,事件冒泡。

默认false,即事件冒泡。Jquery的e.stopPropagation会阻止冒泡,意思就是到我为止,我的爹和祖宗的事件就不要触发了。

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
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡与事件捕获</title>
<style>
#parent {
height: 300px;
background-color: #0094ff;
}
#child {
height: 100px;
background-color: #cc66dd;
}
</style>
</head>
<body>
<div id="parent">
  <div id="child" class="child">子盒子</div>
</div>
<script>
// 事件冒泡
document.getElementById("parent").addEventListener("click", function(e) {
alert("parent事件被触发," + this.id);
})
document.getElementById("child").addEventListener("click", function(e) {
alert("child事件被触发," + this.id)
})
</script>
</body>
</html>

结果如下:

1
2
child事件被触发,child
parent事件被触发,parent

结论:先child,然后parent。事件的触发顺序自内向外,这就是事件冒泡。

事件捕获

指从document到触发事件的那个节点,即自上而下的去触发事件,触发顺序自外向内。

现在改变绑定事件方法的第三个参数值为true:

1
2
3
4
5
6
7
// 事件捕获
document.getElementById("parent").addEventListener("click", function(e) {
alert("parent事件被触发," + e.target.id);
}, true)
document.getElementById("child").addEventListener("click", function(e) {
alert("child事件被触发," + e.target.id)
}, true)

结果如下:

1
2
3
// 若点击#child盒子, 会触发两次, 点击#parent盒子只触发一次
parent事件被触发,child
child事件被触发,child

结论:先parent,然后child。事件触发顺序变更为自外向内,这就是事件捕获。

e.target与e.currentTarget

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style type="text/css" rel="stylesheet">
#fa{
width: 100%;
height: 170px;
padding: 20px 0px;
background-color: cadetblue;
}
#son{
width: 100%;
height: 20px;
padding: 30px 0px;
background-color: black;
color: white;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body>
<div id="fa" onmousedown="getEventTrigger(event)">
<p id="son" onmousedown="getEventTrigger(event)">点我试试</p>
</div>
</body>
<script type="text/javascript">
var fa = document.getElementById('fa');
var son = document.getElementById('son');


function getEventTrigger(event)
{
x=event.currentTarget;
y=event.target;
alert("currentTarget 指向:" + x.id + ", target指向:" + y.id);
}
</script>
</html>

当点击idsonp元素时,执行的是p元素上绑定的事件,此时,事件监听的对象是p元素,目标也是p元素,结果currentTarget指向:sontarget指向:son

所以说currentTargetp元素,target也是p元素;当事件冒泡到它的父级idfa的元素div,触发了绑定在div上的事件,而这时,事件监听的对象是div,目标元素依然是p元素,也就是说,这时的currentTarget指向divtarget依然指向p元素

*** 由此我们可以得出: ***

e.currentTarget指的是注册了事件监听器的对象,而e.target指的是该对象里的子对象,也是触发这个事件的对象!