事件 触发 / 传播

61 阅读2分钟

1、事件传播

js
    当我们在子元素内触发了一个事件的时候,他的对应的父元素也会触发相同的事件

事件传播的两种方式:冒泡与捕获

js
    目标:我们点击的元素就是目标
    
    冒泡:从目标开始,逐层向上传递事件,这个过程叫做 事件冒泡
            1. 目标
            2. 目标的父元素
            3. 目标的父元素的父元素
            4. 目标的父元素的父元素.....
            5. body
            6. document
            7. window
    注意: 事件传播的时候, 只要触发了对应的事件, 那么传播一定会传递上去, 
          哪怕中间的一些元素没有绑定对应的事件
     
     捕获:   从页面的最顶层, 一直向下传递到 目标
             1. window
             2. document
             3. body
             4. 目标的父元素
             5. 目标
     冒泡和捕获, 只有执行顺序的区别, 其他的没有任何区别
js
    这种绑定方式只能完成 冒泡
        box1.onclick = function () {
            console.log('box11111111111111111')
        }
        box2.onclick = function () {
            console.log('box22222222222222')
        }
        document.body.onclick = function () {
            console.log('body.............')
        }
js
    // DOM元素.addEventListener('事件类型', 事件处理函数, 
    一个布尔值决定当前的传播方式)     
    第三个参数默认为 false, 代表 传播方式为 冒泡
        box1.addEventListener(
            'click',
            function () {
                console.log('box11111111111111111111111111111')
            },
            true
        )

        box2.addEventListener('click', function () {
            console.log('box22222222222222222222222222')
        }, true)

        document.body.addEventListener('click', function () {
            console.log('body........................')
        }, true)

事件委托

js
    事件委托
        
              因为 JS 中 事件的传播方式默认是 冒泡
              所以我们触发了子元素的事件时, 会将事件传递给父级
         
              这是冒泡的核心, 我们的事件委托就是利用了 事件冒泡完成的
         
              其实就是将子级的事件, 委托给共同的父级
         
         
          
          优点:
                1.替代循环绑定事件的操作,减少内存消耗,提高性能。比如:
                    在 table 上代理所有 tdclick 事件
                    在 ul 上代理所有 lclick 事件
                2.简化了 dom 节点更新时,相应事件的更新。比如:
                    不用在新添加的 li 绑定 click 事件
                    当删除某个 li 时,不用移解绑上面的 click 事件
           缺点:
                1.事件委托基于冒泡,对于不冒泡的事件不支持.
                2.层级过多,冒泡过程中,可能会被某层阻止掉
                理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。
                所以建议就近委托,比如在3table 上代理 td ,而不是在 document 上代理 td

阻止事件冒泡与默认行为

js
    // 禁止事件冒泡
    e.stopPropagation();
    
    // 禁止默认行为
    e.preventDefault()