zoukankan      html  css  js  c++  java
  • 事件冒泡、事件捕获、事件委托

    首先介绍个方法

    element.addEventListener(event, function, useCapture)

    addEventListener方法原生的JS方法,用来为一个特定的元素绑定一个事件处理函数。

    三个参数分别:

    1. event: 事件类型
    2. function: 事件处理函数
    3. useCapture: 控制事件阶段

    第三个参数useCapture是boolean类型:

    默认是false,表示在事件冒泡的阶段调用事件处理函数,

    如果设置为 true,则表示在事件捕获的阶段调用事件处理函数。

    事件冒泡

    当一个元素接收到事件的时候 会把他接收到的事件传给自己的父级,一直到window。

    即指子元素的事件向父元素传递的过程。

    例如:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡</title>
    </head>
    <body>
    <div>
        <p>
            <button id="b1">点我</button>
        </p>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script>
        /* 因为监听函数addEventListener第三个参数默认为false
            因此直接使用click、focus等函数,默认就是冒泡事件 */
        $('div').click(function () {
            console.log('我是div标签');
        });
        
        $('p').click(function () {
            console.log('我是一个p标签');
        });
        
        // $('#b1')[0] JQ原生转DOM元素
        $('#b1')[0].addEventListener('click', function () {
            console.log('我是那个按钮!');
        }, false)
    </script>
    </body>
    </html>

    当点击按钮后,事件会从子元素(button)一直传递到父元素window,结果:

    事件捕获

    事件捕获与事件冒泡相反,事件的传递从父元素向下传递到子元素。

    即指父元素的事件向子元素传递的过程。

    例如:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>事件捕获</title>
    </head>
    <body>
    <div>
        <p>
            <button id="b1">点我</button>
        </p>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script>
        // 设置为true代表事件捕获
        $('div')[0].addEventListener('click', function () {
            console.log('我是div标签');
        }, true);
    
        $('p')[0].addEventListener('click', function () {
            console.log('我是一个p标签');
        }, true);
    
        // $('#b1')[0] JQ原生转DOM元素
        $('#b1')[0].addEventListener('click', function () {
            console.log('我是那个按钮!');
        }, true)
    </script>
    </body>
    </html>

    当点击按钮后,事件会从父元素window一直传递到子元素(button),结果:

    事件冒泡与事件捕获的关系

    即:事件捕获先发生,再到事件冒泡

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡与捕获</title>
    </head>
    <body>
    <div>
        <p>
            <button id="b1">点我</button>
        </p>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script>
        // 事件捕获
        $('div')[0].addEventListener('click', function () {
            console.log('我是div标签');
        }, true);
        // 事件冒泡
        $('div')[0].addEventListener('click', function () {
            console.log('我是div标签');
        }, false);
    
        $('p')[0].addEventListener('click', function () {
            console.log('我是一个p标签');
        }, true);
        $('p')[0].addEventListener('click', function () {
            console.log('我是一个p标签');
        }, false);
    
        $('#b1')[0].addEventListener('click', function () {
            console.log('我是那个按钮!');
        }, true)
        $('#b1')[0].addEventListener('click', function () {
            console.log('我是那个按钮!');
        }, false)
    </script>
    </body>
    </html>

    当点击按钮后,先发生事件捕获,再发生事件冒泡,结果:

    事件委托

    事件委托是通过事件冒泡的原理,利用父标签去捕获子标签的事件。

    语法:
    $("table").on("click", "button", function () {
      // JS代码
    })
    
    解释:给table绑定一个点击事件,但是是通过button触发的。

    注意事项1:
    像click、keydown等DOM中定义的事件,我们都可以使用`.on()`方法来绑定事件,但是`hover`这种jQuery中定义的事件就不能用`.on()`方法来绑定了,
    也就是说hover()方法不能直接使用事件委托,想使用事件委托的方式绑定hover事件处理函数,可以参照如下代码分两步绑定事件:

    $('ul').on('mouseenter', 'li', function() {//绑定鼠标进入事件
        $(this).addClass('hover');
    });
    $('ul').on('mouseleave', 'li', function() {//绑定鼠标划出事件
        $(this).removeClass('hover');
    });

    注意事项2
    关于this:谁触发这个事件,this就指向谁。
    例如:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    </head>
    <body>
    <div id="div">
        <p id="p">
            <input type="button" value="点我" id="btn">
        </p>
    </div>
    
    <script type="text/javascript">
        $("#div").click(function () {
            //点击按钮,经过事件冒泡,触发这个事件
            //此时this是代表div的,虽然点击的是那个按钮
            //但是实际上是经过冒泡后,div自己触发的这个事件,所有this是div
            console.log(this);
        });
    
        //任意注释一个script标签测试另一个标签
        
        $("#div").on("click", "#btn", function () {
            //事件委托,给div绑定了一个事件,点击按钮触发这个事件
            //此时this是代表按钮btn的,虽然绑定的事件是div
            //但是触发这个事件的是btn,所以this是btn
            console.log(this);
        })
    
    </script>
    </body>
    </html>
  • 相关阅读:
    java 自定义表单 动态表单 表单设计器 工作流引擎 flowable 设计方案
    设置Springboot返回jackson数据序列化
    SpringCloud Alibaba 报 AbstractMethodError 是版本兼容问题导致
    Springboot进阶JDBC、Druid、Mybatis、Swagger、SpringMVC、Mail
    java 自定义表单 动态表单 表单设计器 工作流引擎 flowable 项目源码
    springcloud Alibaba 微服务 flowable 工作流 自定义表单 vue.js前后分离
    ClassLoader读取文件,springboot打jar包后读取不到
    Nginx/Tomcat/Apache的优缺点和区别
    Swagger3 相比2配置变了
    webloginc配置项目根目录
  • 原文地址:https://www.cnblogs.com/Zzbj/p/15431038.html
Copyright © 2011-2022 走看看