美文网首页
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