美文网首页
事件冒泡和事件捕获

事件冒泡和事件捕获

作者: YoungEvita | 来源:发表于2018-03-28 19:09 被阅读0次

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-1

click 事件传播顺序:
<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

相关文章

网友评论

      本文标题:事件冒泡和事件捕获

      本文链接:https://www.haomeiwen.com/subject/vdnscftx.html