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

事件冒泡和事件捕获

作者: 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