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

在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
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 8,925评论 1 11
  • js之事件机制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驱动...
    道无虚阅读 7,321评论 0 2
  • 以下文章为转载,对理解JavaScript中的事件处理机制很有帮助,浅显易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy阅读 8,227评论 1 10
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 5,043评论 3 11
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 28,486评论 1 45

友情链接更多精彩内容