事件冒泡和事件捕获

起因:今天在封装一个bind函数的时候,发现el.addEventListener函数支持第三个参数,useCapture:是否使用事件捕获,觉得有点模糊


  • Js事件流

    页面的哪一部分会拥有某个特定事件,例子:在纸上画一组同心圆,如果手指放在同心圆上,那么手指向的不是一个圆,而是纸上所有的圆。在页面中也是,如果点击了某个按钮,同时也单击了按钮的容器元素,甚至也单击了整个页面

    事件流:页面接收事件的顺序,IE和Netscape最开始提出了两种概念,两种事件冒泡流事件捕获流

    <!-- 假如有这样一段相同的html -->
<!DOCTYPE html>
<html>
<head><title>bubbling and capture</title></head>
<body>
<div id="myDiv">Click me</div>
</body>
</html>
  • 事件冒泡(event bubbling)

    IE提出的事件处理方式,即事件开始时,由最具体的元素接收,然后逐级向上传播到不具体的节点

    如果点击例子中的div元素,那么这个click的事件传播顺序如下:div -> body -> html -> document

    也就是说,click事件首先会在div元素上触发,这个元素就是我们单击的元素,然后click事件会沿着DOM树向上传播,在每一级节点都会发生,直到传播到document对象

    所有浏览器都支持事件冒泡,但是在具体实现上会有些许的差别,例如IE5.5以及更早版本中的事件冒泡会跳过Html元素,直接从body跳到document元素,而IE9,Firefox,Chrome,Safari则将事件一直冒泡到window对象

  • 事件捕获(event capturing)

    Netscape网井团队则题除另一种事件流叫做事件捕获,事件捕获的思想是不太具体的节点应该更早的接收到事件,而具体的节点应该最后接收到事件,事件捕获的用意在于事件达到预计目标之前捕获他,如果还是以上面的例子,单击div

    那么触发顺序会是这样 document -> html -> body -> div

    在事件捕获过程中,document对象首先接收到click事件,然后事件沿DOM树依次向下,一直传播到时间的实际目标即div元素

    虽然Netscape是开发这种事件流,但是目前所有较新的浏览器都支持这种事件流模型,尽管“DOM2级事件”规范要求事件应该从document对象开始传播,但是这些浏览器都是从window对象开始捕获事件

    由于老版本浏览器不支持,所以很少使用事件捕获,推荐放心使用事件冒泡,在有特殊需求时再使用事件捕获

  • DOM事件流

    "DOM2级别事件"什么是DOM2级别规定的事件流包括三个阶段

    事件捕获阶段 处于目标阶段 事件冒泡阶段
    事件未处于目标,事件传递按照从大到小,从外层顺着DOM树向目标传递,触发顺序,从外到里 处于目标阶段:事件会在目标元素上发生,并且在事件处理中堪称冒泡阶段的一部分 事件冒泡阶段:事件从目标元素开始,顺着DOM树往外传递,依次到父容器,body,html,document部分浏览器会到window
  • 什么是DOM2级别?什么是DOM0级别?什么是DOM事件处理程序等级

    事件:用户或浏览器自身执行的某种动作,例如click,load,mouseover都是事件名字,而相应某个事件的函数,就叫做事件处理程序,事件处理程序的名字以on开头,例如click事件的处理程序就是onclick,load事件的处理陈鼓型就是onload

    • HTML事件处理程序

      某个html元素支持某种事件,都可以使用一个与对应时间处理程序同名的html属性来指定,这个属性的值则是能够执行的javascript代码,例如

      <div onclick="alert(1)"></div>

      该事件触发于:冒泡阶段触发

    • DOM0级事件处理程序

      html事件处理程序javascript逻辑和html耦合太强

      DOM0级事件处理程序写法

          var btn = document.getElementById('myBtn')
      btn.onclick= function(){
      alert(this.id)
      }

      此处的this指向的是这个触发元素,并且可以通过this对象访问元素的任何属性和方法,以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

      移除事件监听btn.onclick = null

    • DOM2级事件处理程序

      两个方法:addEventListenerremoveEventListener

      所有的DOM节点都包含这两个方法,并且接受三个参数,要处理的事件名,作为事件处理函数的函数和一个布尔值,最后这个布尔值如果是true,表示在捕获阶段调用事件处理程序,如果是false则表示在冒泡阶段调用事件处理程序

      而事件流的顺序是捕获-目标-冒泡,捕获阶段会在冒泡事件处理之前,所以改为true的话有可能会影响正常的时间顺序

      demo如下:

          var btn = document.getElementById('myBtn')
      btn.addEventListener('click',function(){
      alert(this.id)
      },false)

      DOM2级方法添加事件处理程序的好处是可以添加多个事件处理程序,而前两个则是会替换掉事件处理程序,因为属性只有一个,而元素的方法也会重写

      但是也意味着,不能通过重写来移除事件处理程序,所以通过removeEventListener来移除事件处理程序,并且匿名函数无法移除

      大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器,最好只在需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段,如果不是特别需要,不建议在时间捕获阶段注册事件处理程序

    • IE事件处理程序

      IE中实现了与DOM中类似的两个方法attachEventdetachEvent,但是仅接受两个参数,一个是事件处理程序名称与事件处理函数,由于IE8以及更早的版本只支持事件冒泡,所以通过attachEvent添加的事件处理程序都会被添加到事件冒泡阶段

      需要注意的是:

      1.attachEvent和DOM级方法主要区别在事件处理程序的作用域,DOM0级会在所属元素的作用域内,而attachEvent事件处理程序会在全局作用域中运行,因此在attachEvent添加的函数中,this指向window

      2.attachEvent添加多个事件时候时,不是按照添加顺序执行,而是按照相反的顺序执行,后添加,先执行

总结

  • el.addEventListener函数的第三个参数问题得到了解决,使用这种方法表示绑定DOM2级别的事件监听程序,可以重复指定,第三个参数表示是否在捕获阶段处理事件,捕获-》 目标 -》 冒泡
  • 第三个参数默认false,如没有特殊情况不推荐使用在捕获阶段处理时间程序
  • 了解了 事件流 ,捕获和冒泡 ,DOM事件类型级别(HTML级事件处理程序,DOM0级事件处理程序,DOM2级事件处理程序,IE事件处理程序)
  • 事件流过程,先从外到内,捕获阶段,到达目标阶段,从内到外冒泡

Javascript中的事件冒泡与捕获的更多相关文章

  1. javascript中的事件冒泡、事件捕获和事件执行顺序

    谈起JavaScript的 事件,事件冒泡.事件捕获.阻止默认事件这三个话题,无论是面试还是在平时的工作中,都很难避免. DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有 ...

  2. javascript中的事件冒泡和事件捕获

    1.事件冒泡 IE 的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档).以下面的HTML ...

  3. JavaScript中的事件冒泡?事件传播的解释

    注:本文来源  可译网 事件冒泡是你在学习javaScript旅途中遇到的一个术语,它涉及到当一个元素被另一个元素嵌套时调用事件处理的顺序,并且两个元素注册了同一个事件(例如,点击事件). 但是事件冒 ...

  4. JavaScript权威设计--事件冒泡,捕获,事件句柄,事件源,事件对象(简要学习笔记十八)

    1.事件冒泡与事件捕获 2.事件与事件句柄   3.事件委托:利用事件的冒泡技术.子元素的事件最终会冒泡到父元素直到跟节点.事件监听会分析从子元素冒泡上来的事件. 事件委托的好处:     1.每个函 ...

  5. JavaScript中的事件冒泡机制

    事件冒泡机制 事件冒泡发生的条件:当为多个嵌套的元素设置了相同的事件处理程序,它们将触发事件冒泡机制.在事件冒泡中,最内部的元素将首先触发其事件,然后是栈内的下一个元素触发该事件,以此类推,直到到达最 ...

  6. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  7. javascript 中的事件机制

    1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

  8. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  9. javascript中的事件委托

    这几天看到一个面试题,大概就是,让你给1000个li都添加一个click事件,应该怎么添加?大多数人第一开始的感觉可能就是,每个li上边都添加一个呗,那要是这样的话,估计面试的时候就会GG了,这里就是 ...

随机推荐

  1. 应急响应-PDCERF模型 (转)

    目录 应急响应流程 防御模型 SDL 应急响应流程 很多人认为应急响应就是脸上被黑的机器去查查什么情况,是不是被中了botnet病毒.是不是被人中了rootkit等,是不是被挂了webshell等.应 ...

  2. eclipse下执行maprdeuc程序报错 java.lang.ClassNotFoundException

    最近遇到一个问题,不知怎么突然运行hadoop的map程序报错,困扰了我很久,现在来给大家分享分享.. 错误信息 2017-05-18 21:34:22,104 INFO [main] client. ...

  3. mysql:如何利用覆盖索引避免回表优化查询

    说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml 17 ...

  4. JavaScript中是如何定义私有变量的

    前言 JavaScript并不像别的语言,能使用关键字来声明私有变量. 我了解的JavaScript能用来声明私有变量的方式有两种,一种是使用闭包,一种是使用WeakMap. 闭包 闭包的描述有很多种 ...

  5. 【函数分享】每日PHP函数分享(2021-2-6)

    array_combine - 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值 说明: array_combine ( array $keys , array $values ) : ...

  6. 2020 CCPC-Wannafly Winter Camp Day2

    2020 CCPC-Wannafly Winter Camp Day2 A 托米的字符串 虽然每个子串出现的概率是相同的,但是同一长度的子串个数是不同的,所以要分别处理.计算出某一长度的情况下,元音字 ...

  7. 三维CAD——基于B_rep的建模操作

    内容来自高老师的<三维CAD建模>课,本文就主要介绍半边结构和欧拉操作以及代码实现. 1. 边界表示法及其数据结构 · 拓扑结构 a.拓扑元素:面.边.点.体 b.拓扑关系:9种.V{V} ...

  8. Java-Graphics类的绘图方法实现

    Java-Graphics(画图类) 就比如画一个矩形,你给出矩形左上角坐标,再给出矩形长度和宽度就可以在JFrame上画出来一个矩形 除了矩形之外,还可以画椭圆.圆.圆弧.线段.多边形.图像等 下面 ...

  9. 博弈论入门——Nim游戏引入

    说实话,我真的对这个游戏看得是一脸懵逼,因为(我太弱了)我没有明白一些变量的意思,所以一直很懵,现在才明白,这让我明白博弈论(还可以骗钱)博大精深; 以下是我自己思考的过程,也许不严谨,但是最终明白了 ...

  10. python的threading的使用(join方法,多线程,锁threading.Lock和threading.Condition

    一.开启多线程方法一 import threading,time def write1(): for i in range(1,5): print('1') time.sleep(1) def wri ...