javascript中有两种事件传播模式:
- 捕获模式(capturing)
- 冒泡模式(bubbling)
捕获模式
当事件发生时,该事件首先被最外层元素接收到,然后依次向内层元素传播(从外向内)
冒泡模式
当事件发生时,该事件首先被最内层元素接受到,然后依次向外层元素传播。
使用方式
用哪种事件传播方式完全是我们自己说了算的,我们可以使用addEventListener函数,useCapture是一个布尔类型变量,如果传入true,则使用捕获模式,如果传入falst,则使用冒泡模式。
addEventListener(type, listener, useCapture)
例子
<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>
使用事件捕获模式注册事件监听
var outerElement = document.getElementById('outerMost');
var middleElement = document.getElementById('middle');
var innerElement = document.getElementById('innerMost');
outerElement.addEventListener('click', function () {
console.log('trigger outermost div');
}, true);
middleElement.addEventListener('click', function () {
console.log('trigger middle div');
}, true);
innerElement.addEventListener('click', function () {
console.log('trigger innermost button');
}, true);
preventDefault 及 stopPropagation函数区别
点击上面的click发现innerElement的click事件未打印出日志,这是因为点击了链接,页面立即跳转到了当前页面,这是链接元素的一个默认特性。虽然我们的监听函数被执行了,但是有时候我们不想这个默认特性被执行。以为了“阻止”元素的“默认特性”,所以事件对象中有了一个preventDefault方法,如下:
innerElement.addEventListener('click', function (event) {
event.preventDefault();
console.log('trigger innermost button');
}, true);
stopPropagation
当我们只想触发a元素的click事件时,我们不想触发其他的,可以使用stopPropagation函数:
innerElement.addEventListener('click', function (event) {
event.preventDefault();
event.stopPropagation();
console.log('trigger innermost button');
}, true);