1 事件冒泡与事件捕获
1.1 事件冒泡(event bubbling)
事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
<!DOCTYPE html>
<html>
<head>
<title>Event bubbling</title>
</head>
<body>
<div id="myDiv"></div>
</body>
</html>
当点击“myDiv”时,click事件先在此div上触发,然后click事件沿DOM树向上传播,直至document对象。如图 1-1所示:
图 1-1click 事件传播顺序:
<div> --> <body> --> <html> --> document
1.2 事件捕获(event capturing)
事件捕获思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。
当点击“myDiv”时,document对象会首先接收到click事件,然后事件沿DOM树依次向下,一直传播到事件到实际目标,<div>元素。如图 1-2所示:
图 1-2
click事件传播顺序:
document --> <html> --> <body> --> <div>
1.3 实现
可通过设置addEventListener的第三个参数来设置是使用事件冒泡还是事件捕获。第三个参数默认为false,表示事件冒泡;true表示事件捕获。
<!DOCTYPE html>
<html>
<head>
<title>Event bubbling or capturing</title>
</head>
<body>
<div id="parentDiv">
<div id="childDiv">Click me</div>
</div>
</body>
</html>
事件冒泡
document.getElementById("parentDiv").addEventListener('click', function(event) {
console.log('触发父元素点击事件');
}, false);
document.getElementById("childDiv").addEventListener('click', function(event) {
console.log('触发子元素点击事件');
}, false)
点击Click me 会输出:
触发子元素点击事件
触发父元素点击事件
事件捕获
document.getElementById("parentDiv").addEventListener('click', function(event) {
console.log('触发父元素点击事件');
}, true);
document.getElementById("childDiv").addEventListener('click', function(event) {
console.log('触发子元素点击事件');
}, true)
点击Click me 会输出:
触发父元素点击事件
触发子元素点击事件
2 阻止冒泡与阻止默认事件
stopPropagation 阻止事件向父元素传递;
preventDefault 阻止默认事件的触发,比如a链接的跳转;
return false 具备以上两种效果。
<body>
<div id="parentDiv">
<a href="http://www.baidu.com">Click me</a>
</div>
</body>
1.
不做任何处理时
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
console.log('forward to Baidu');
});
点击click me链接时:
输出 forward to Baidu,然后跳转到百度页面;
输出 This is a parent div.
2.
stopPropagation
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
event.stopPropagation();
console.log('forward to Baidu');
});
点击click me链接时:
输出 forward to Baidu,然后跳转到百度页面;
3.
preventDefault
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
event.preventDefault();
console.log('forward to Baidu');
});
点击click me链接时:
输出 forward to Baidu
输出 This is a parent div.
4.
同时使用preventDefault和stopPropagation
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
event.preventDefault();
event.stopPropagation();
console.log('forward to Baidu');
});
点击click me链接时:
输出 forward to Baidu
5.
retrun false
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
return false;
console.log('forward to Baidu');
});
点击click me链接时:
无任何输出,也不跳转
6.
兼容IE两种写法
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
event = event ? event : window.event;
event.preventDefault();
event.stopPropagation();
console.log('forward to Baidu');
});
$("#parentDiv").on('click', function(event) {
console.log('This is a parent div.');
});
$("a").on('click', function(event) {
if(event && event.stopPropagation){
event.preventDefault();
event.stopPropagation();
}else{ // IE 写法
window.event.cancelBubble = true; // 阻止冒泡
window.event.returnValue = false; // 禁止默认事件
}
console.log('forward to Baidu');
});
点击click me链接时:
输出 forward to Baidu
网友评论