事件:
JavaScript 和 HTML的交互是通过事件实现的,事件发生在传播过程中。
- DOM中事件传播有2种方式:
- 捕获模式(
capturing
),捕获模式又称为“滴流模式”(trickling),就是“从上向下”, - 冒泡模式(
bubbling
),“从下向上”(默认的时间传播方式)
这里的从上而下是以DOM树
为依据,父节点在上,子节点在下。
- 捕获模式(
事件捕获 | 事件冒泡 |
---|---|
事件捕获 | 事件冒泡 |
-
使用
addEventListener(type, listener, useCapture)
来注册事件的时候,第三个参数默认为false
,代表事件捕获方式为冒泡 -
使用
.stopPropagation()
可以阻断事件的传播,当为事件捕获时,阻断事件向下传播,当为事件冒泡时,阻断事件向上传播 -
.preventDefault()
是用来阻止DOM
元素默认的事件的,比如a标签
的跳转动作,表单button
的提交动作,与事件传播关系不大 -
return false;
是JQ
的语法,相当于.stopPropagation()
+.preventDefault()
,原生语法中无效
如下例:
- 使用的是事件捕获模式,在最上层的
outerMost
使用了stopPropagation
,则点击任何一个元素,都只会触发outerMost
的事件 - 使用的是事件捕获模式,所以当点击
innerMost
的时候,DOM事件
并未传递到innerMost
,所以e.preventDefault()
不起作用,a标签
仍然会导致页面跳转
<div id="outerMost" style="border: 1px solid black; width: 150px; height: 120px; padding: 20px;">
outerMost
<div id="middle" style="border: 1px solid black; width: 60px; height: 60px; padding: 20px;">
Middle
<a href="" id="innerMost" style="border: 1px solid black; width: 30px; height: 20px; display: block; margin: 20px;">click</a>
</div>
</div>
<script>
var outerElement = document.getElementById('outerMost');
var middleElement = document.getElementById('middle');
var innerElement = document.getElementById('innerMost');
outerElement.addEventListener('click', function (e) {
console.log('trigger outermost div');
e.stopPropagation();
}, true);
middleElement.addEventListener('click', function (e) {
console.log('trigger middle div');
e.stopPropagation();
}, true);
innerElement.addEventListener('click', function (e) {
console.log('trigger innermost button');
// e.stopPropagation();
e.preventDefault();
}, true);
</script>
进阶:事件流
事件流- 第一阶段:从最顶层window对象传导到目标节点,称为“捕获阶段”(capture phase)。
- 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
- 第三阶段:从目标节点传导回最顶层window对象,称为“冒泡阶段”(bubbling phase)
网友评论