javascript中的事件冒泡理解

 你必须很努力,才能看上去毫不费力

事件冒泡

点击一个div, 最终弹出 div

1
2
3
4
5
6
7
8
9
10
<div>
<p>点我吧</p>
</div>

<script>
let div = document.querySelector("div");
div.onclick=function () {
alert('div');
}
</script>

在div里的p元素同样也绑定一个点击事件, 那么会先弹出p, 然后再弹出div

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div>
<p>点我吧</p>
</div>

<script>
let div = document.querySelector("div");
div.onclick=function () {
alert('div');
};

let p = document.querySelector("p");
p.onclick=function () {
alert('p');
}
</script>

微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是p -> div -> body -> html -> document

阻止事件冒泡

jquery

这样就不再弹出div了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
<div>
<p>点我吧</p>
</div>
<script>
let div = document.querySelector("div");
div.onclick=function (event) {
alert('div');
};

let p = document.querySelector("p");
p.onclick=function () {
alert('p');
event.stopPropagation();
}
</script>

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div>
<p>点我吧</p>
</div>
<script>
let div = document.querySelector("div");
div.onclick=function (event) {
alert('div');
};

let p = document.querySelector("p");
p.onclick=function (e) {
alert('p');
if ( e && e.stopPropagation )
e.stopPropagation();
else
window.event.cancelBubble = true;
}
</script>

事件捕获

网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

上面的例子在事件捕获的概念下发生click事件的顺序应该是document -> html -> body -> div -> p

addEventListener的第三个参数
第一个参数是需要绑定的事件,第二个参数是触发事件后要执行的函数。
而第三个参数默认值是false,表示在事件冒泡的阶段调用事件处理函数,如果参数为true,则表示在事件捕获阶段调用处理函数。

1
element.addEventListener(event, function, useCapture)

拓展浏览器的默认事件

下面这段代码我们点击后超链链是会发送跳转的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div>
<a href="http://www.google.com">点我吧</a>
</div>
<script>
let div = document.querySelector("div");
div.onclick=function (event) {
alert('div');
};

let p = document.querySelector("p");
p.onclick=function (e) {
alert('p');
if ( e && e.stopPropagation )
e.stopPropagation();
else
window.event.cancelBubble = true;
}
</script>

如果我们仅仅想点击,而不想让发送跳转呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div>
<a href="http://www.google.com">点我吧</a>
</div>
<script>
let div = document.querySelector("div");
div.onclick=function (event) {
alert('div');
};

let a = document.querySelector("a");
a.onclick=function (e) {
alert('a');
if ( e && e.preventDefault )
e.preventDefault();
else
window.event.returnValue = false;
return false;
}
</script>
</body>