美文网首页
JavaScript 几个比较零碎的点 -- 阻止事件冒泡

JavaScript 几个比较零碎的点 -- 阻止事件冒泡

作者: 人话博客 | 来源:发表于2019-03-25 23:26 被阅读0次

    在W3C的标准下.事件有两个模型.

    事件冒泡事件捕获

    除非情况特殊,我们在默认情况下都是使用的事件冒泡模式.

    el.addEventListener('click', function () {
        console.log('xxxx')
    } , false)
    

    取消事件冒泡

    事件会冒泡需要几个前提

    • 首先,模式使用的是事件冒泡模式(而不是事件捕获)
    • 几个元素之间包含嵌套关系.
    • 几个嵌套元素中,点击的元素的外部元素[恰好]也绑定了同类型事件响应函数.

    其实,很多情况下,我们根本就不需要执行所谓的取消事件冒泡

    原因也很简单:

    • 大多数HTML元素都只是为了展示数据的.一般有事件交互的很少.
    • 一般有事件交互的都是单纯的那个交互的元素绑定了事件响应函数,而和它有嵌套关系的元素虽然事件存在,但是没有绑定事件响应函数,所以就没有必要执行阻止事件冒泡
    • 有很多事件压根就不支持事件冒泡,比如常用的表单元素的 input,focus,select 等.

    但是如果实际情况属于下面的场景的话,可能就需要执行阻止事件冒泡了.

    • 有两个(N)元素,它们是嵌套关系.

    • 两个(N)元素都绑定了click事件响应函数,且使用的是事件冒泡模式.

    • 在点击内部元素时,只希望执行点击了的那个元素的click事件响应函数.

    <div class="parent">
        <div class="child"></div>
      </div>
    
    
    parent.addEventListener('click', function () {
        console.log('父元素的事件响应函数被子元素的事件冒泡给触发了')
      }, false)
      child.addEventListener('click', function () {
        console.log('child clicked')
      }, false)
    

    默认情况下,事件冒泡从内往外传递.

    这里我们点击了内部的 .childDIV 元素.

    事件冒泡到了 .parentDIV 元素.

    巧的是 .parent 也绑定了 click 事件响应函数.(然而多数情况是,外部元素一般不会这么巧也会绑定同样的 click 事件响应函数,所以绝大多数情况,我们不需要阻止所谓的取消事件冒泡)

    于是它们就形成了一个我们不想要的因为事件冒泡儿产生的结果.

    child clicked
    父元素的事件响应函数被子元素的事件冒泡给触发了
    

    事件参数

    取消事件冒泡,也有一个前提.

    前提是每一个事件响应函数在执行时,都有一个 e 表示事件参数.

    它保存了当前事件产生的一些必要数据(包括事件源对象,位置坐标等信息)

    
    parent.addEventListener('click', function () {
        console.log('父元素的事件响应函数被子元素的事件冒泡给触发了')
      }, false)
      child.addEventListener('click', function (e) {
        e.stopPropagation() // 取消事件冒泡.
        console.log('child clicked')
      }, false)
    
    

    e 是当前事件响应函数带过来的事件信息对象.
    stopPropagation 是阻止事件冒泡的方法.

    调用 e.stopPropagation() 方法,就可以阻止事件往外传递.

    值的一提的是:

    stopPropagation 是 W3C 标准里定义的阻止事件冒泡的方法.

    既然是 W3C 标准,那么肯定有的浏览器不是这么来阻止事件冒泡的.

    对的,说的就是你 IE9 以及以下版本.

    你说,如果仅仅只是一个方法不一致也就罢了...

    对于 IE9 以及以下版本 获取事件对象的方式也不一样.

    在老版本IE中,事件对象,不是事件响应函数带的那个事件参数.
    而是使用 window.event 来获取.
    同时,阻止事件冒泡也不是 stopPropagation() ,而是 window.event.cancelBubble=true.

    所以,如果是在一个IE低版本浏览器里.
    阻止事件冒泡的写法是下面这样.

    child.onclick = function () {
        var event = window.event
        event.cancelBubble = true
    }
    
    or 
    
    child.attachEvent('onclick', function () {
         var event = window.event
        event.cancelBubble = true
    })
    

    取消事件冒泡兼容方法

    function cancelBubble (e) {
        let e = e || window.event
        if (e.stopPropagation) {
            e.stopPropagation()
        } else {
            e.cancelBubble = true
        }
    }
    

    相关文章

      网友评论

          本文标题:JavaScript 几个比较零碎的点 -- 阻止事件冒泡

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