JS事件流
- 事件流分三个阶段:1-5 捕获阶段、5-6 目标阶段、 6-10 冒泡阶段
- IE6、7、8只支持冒泡流
事件捕获和事件冒泡
- 事件捕获:最外层元素先捕获事件,事件向下逐级捕获。外 -> 里
- 事件冒泡:子元素响应事件,父元素也响应事件,事件向上逐级传递。里 -> 外
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>
<a href="#">超链接</a>
</li>
</ul>
</body>
</html>
<script>
let oUl = document.querySelector('ul');
let oLi = document.querySelector('li');
let oA = document.querySelector('a');
...
</script>
事件冒泡的验证过程
// 事件冒泡 输出 a > li > ul
// oUl.onclick = function (e) {
// console.log('ul标签点击');
// };
//
// oLi.onclick = function (e) {
// console.log('li标签点击');
// };
//
// oA.onclick = function (e) {
// console.log('a标签点击');
// };
// 事件冒泡 输出 a > li > ul
oUl.addEventListener('click', function () {
console.log('ul标签点击');
});
oLi.addEventListener('click', function () {
console.log('li标签点击');
});
oA.addEventListener('click', function () {
console.log('a标签点击');
});
事件委托(事件捕获)验证过程
// 事件捕获 输出 ul > li > a
oUl.addEventListener('click', function () {
console.log('捕获Ul的点击事件');
}, true);
oLi.addEventListener('click', function () {
console.log('捕获li的点击事件');
}, true);
oA.addEventListener('click', function () {
console.log('捕获a的点击事件');
}, true)
事件是先捕获,再冒泡的
// 事件捕获 输出 ul > li > a
oUl.addEventListener('click', function () {
console.log('捕获Ul的点击事件');
}, true);
oLi.addEventListener('click', function () {
console.log('捕获li的点击事件');
}, true);
oA.addEventListener('click', function () {
console.log('捕获a的点击事件');
}, true)
// 事件冒泡 输出 a > li > ul
oUl.addEventListener('click', function () {
console.log('ul标签点击');
});
oLi.addEventListener('click', function () {
console.log('li标签点击');
});
oA.addEventListener('click', function () {
console.log('a标签点击');
});
// 输出 捕获ul > 捕获li > 捕获a > 冒泡a > 冒泡li > 冒泡ul
特殊情况:如果绑定冒泡事件在前,委托事件在后,目标元素(实际点击的元素)在目标阶段会先触发冒泡,再触发委托事件
// 事件冒泡
oUl.addEventListener('click', function () {
console.log('ul标签点击');
});
oLi.addEventListener('click', function () {
console.log('li标签点击');
});
oA.addEventListener('click', function () {
console.log('a标签点击');
});
// 事件捕获
oUl.addEventListener('click', function () {
console.log('捕获Ul的点击事件');
}, true);
oLi.addEventListener('click', function () {
console.log('捕获li的点击事件');
}, true);
oA.addEventListener('click', function () {
console.log('捕获a的点击事件');
}, true)
// 输出 捕获ul > 捕获li > 冒泡a > 捕获a > 冒泡li > 冒泡ul
阻止事件向上冒泡
oUl.addEventListener('click', function () {
console.log('ul标签点击');
});
oLi.addEventListener('click', function () {
console.log('li标签点击');
});
oA.addEventListener('click', function (e) {
e.stopPropagation();
console.log('a标签点击');
});
// 输出 a标签点击
阻止事件向下捕获
oUl.addEventListener('click', function (e) {
e.stopPropagation();
console.log('捕获Ul的点击事件');
}, true);
oLi.addEventListener('click', function () {
console.log('捕获li的点击事件');
}, true);
oA.addEventListener('click', function () {
console.log('捕获a的点击事件');
}, true)
// 输出 捕获Ul的点击事件