美文网首页
Javascript 事件代理、冒泡和捕获

Javascript 事件代理、冒泡和捕获

作者: 我是一个前端 | 来源:发表于2019-02-13 16:16 被阅读0次

    2019开工荒了两天,赶紧开始!

    为什么写事件代理、冒泡、捕获,首先冒泡和捕获是js事件的核心基础,事件代理原理来自冒泡和捕获。

    此文章略过标准浏览器和非标准浏览器的事件流讲解,原因很简单我们现在已经幸福了,已经不考虑IE6、7、8了

    直接说现代浏览器事件流,用两张图看看什么是冒泡 什么是捕获,其实从字面意思大概能看出 一个是向外一个是向内。

    事件冒泡 事件捕获

    标准事件流

    1、捕获阶段 (先从最外层向内查找)
    2、目标阶段(找到事件元(当前点击的dom))
    3、冒泡阶段(向上冒泡传递事件)

    事件冒泡

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>冒泡</title>
    </head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        div {
            padding: 30px;
        }
        
        .div1 {
            background: red
        }
        
        .div2 {
            background: blueviolet
        }
        
        .div3 {
            background: yellowgreen
        }
    </style>
    
    <body>
        <div class="div1">
            父
            <div class="div2">
                子
                <div class="div3">
                    孙
                </div>
            </div>
        </div>
        <script>
           // javascript事件绑定addEventListener接收三个参数,
           //  1、事件名称字符串且不带on
           //  2、回调函数
           //  3、事件流方式(默认为冒泡(false),捕获为true)
            window.onload = function() {
                document.querySelector('.div1').addEventListener('click', function() {
                    console.log('点击div1')
                }, false)
                document.querySelector('.div2').addEventListener('click', function() {
                    console.log('点击div2')
                }, false)
                document.querySelector('.div3').addEventListener('click', function() {
                    console.log('点击div3')
                }, false)
            }
        </script>
    </body>
    
    </html>
    

    先演示下冒泡


    事件冒泡

    事件捕获

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>冒泡</title>
    </head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        div {
            padding: 30px;
        }
        
        .div1 {
            background: red
        }
        
        .div2 {
            background: blueviolet
        }
        
        .div3 {
            background: yellowgreen
        }
    </style>
    
    <body>
        <div class="div1">
            父
            <div class="div2">
                子
                <div class="div3">
                    孙
                </div>
            </div>
        </div>
        <script>
            window.onload = function() {
                document.querySelector('.div1').addEventListener('click', function(e) {
                    console.log('点击父元素')
                }, true)
                document.querySelector('.div2').addEventListener('click', function(e) {
                    console.log('点击子元素')
                }, true)
                document.querySelector('.div3').addEventListener('click', function(e) {
                    console.log('点击孙子元素')
                }, true)
            }
        </script>
    </body>
    
    </html>
    

    看看效果


    事件捕获

    事件委托

    我理解的事件委托的好处有两点
    1、减少事件绑定次数
    2、可以给未知元素绑定事件(例如动态渲染的List)

    其原理就是利用事件冒泡向外传递的特性,下面代码解析一下:
    同样忽略低版本浏览器获取当前target兼容性问题

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>冒泡</title>
    </head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        div {
            padding: 30px;
            border: 1px solid red
        }
        
        div span {
            display: inline-block;
            padding: 10px;
            border: 1px solid blueviolet
        }
    </style>
    
    <body>
        <div class="div1">
            <span>1</span>
            <span>2</span>
            <span>3</span>
            <span>4</span>
        </div>
        <script>
            window.onload = function() {
                document.querySelector('.div1').addEventListener('click', function(e) {
                    //回调函数e为事件对象,同伙事件对象可以获取当前点击dom
                    console.log(e.target)
                    //获取到当前事件源(dom)后再去搞一些你想搞的事情就ok了
    
                    //搞事情代码
                }, false)
    
            }
        </script>
    </body>
    
    </html>
    

    老规矩,看看效果


    事件委托

    最后顺便说一下事件对象功能很全的,看下图能获取到很多当前dom的周边,可以搞好多其它的事情。


    事件对象

    感谢阅读,欢迎吐槽!谢谢!

    相关文章

      网友评论

          本文标题:Javascript 事件代理、冒泡和捕获

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