DOM事件流

事件流描述的是从页面中接收事件的顺序。说白了,我作了一件事,这件事怎么被别人知道的,这个顺序就是事件流。 可是对于这个顺序,有些人产生了分歧。IE和Netscape提出了几乎是彻底相反的事件流的概念。因而有了(IE)事件冒泡流和(Netscape)事件捕获流。html


事件冒泡

事件冒泡:事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,而后逐级向上传播到较为不具体的节点(文档)。 以下示例:浏览器

<!DOCTYPE html>
<html>
    <head>
        <title>事件冒泡</title>
    </head>
    <body>
        <div id="myDiv">点我</div>
    </body>
</html>
复制代码

若是你点击了里面的<div>元素,那么click事件就会按照下面的顺序传播执行:bash

  1. <div>
  2. <body>
  3. <html>
  4. document

click事件会首先在<div>元素身上发生,这个元素就是咱们点击的的元素,而后才是上一层元素,一直到document元素。函数


事件捕获

事件捕获:不太具体的节点应该更早接收事件,而最具体的节点应该是最后接收到事件。那么点击<div>元素就会如下列顺序执行click事件:this

  1. document
  2. <html>
  3. <body>
  4. <div>

事件捕获过程,document对象首先接收到click事件,而后依次向下,传播到事件的实际目标。spa

DOM事件流

事件流规定包含三个流程:事件捕获阶段,事件冒泡阶段和处于目标阶段。首先发生是事件捕获(截获事件),而后是处于目标阶段接收到事件,最后是事件冒泡阶段(对事件做出相应)。3d

在DOM事件流中,目标元素<div>在事件捕获阶段是不会接受到事件的,下一阶段“处于目标阶段”,事件在<div>上发生,并在事件处理中被当作冒泡阶段的一部分,而后,冒泡阶段发生,事件传播回文档。code


如何用事件流

在上文中的事件处理,就是咱们使用事件流的一种方法,事件是用户或者浏览器自身执行的某种动做,例如'click'、'mouseover'等都是事件的名字,而相应这种操做的函数就叫事件处理程序(事件侦听)。cdn

  • DOM0级处理事件程序

    经过JavaScript指定事件处理程序的传统方法,就是将一个函数赋值给一个事件处理程序属性。每一个元素(包括window和document)都有本身的事件处理程序属性,这些属性所有小写。以下:htm

    var button = document.getElementById('myButton')
    button.onclick = function(){
        alert('hello'+this.id)
    }
    复制代码

    咱们经过文档对象获取到一个button的引用,并给它了一个onclick的事件处理程序。可是须要注意的是:若是这段代码运行在button的后面,可能会出现你怎么点击都没有反应。

    DOM0级方法指定的事件处理程序被认为是元素的方法。所以,这个时候的事件处理程序是在该元素的做用域中执行。因此代码块里面会alert出‘myButton’,往大了说,在这个事件处理程序的做用域中,能够用this访问到该元素的任何方法和属性。这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。

    若是想要删除这个DOM0级事件处理程序,以下:

    button.onclick = null
    复制代码

    再点击就不会有任何反应。

  • DOM2级事件处理程序

    DOM2级事件处理程序定义了两个方法:‘addEventListener()’和‘removeEventListener()’,全部DOM节点都包含这两个方法,而且它们接收3个参数:要处理的事件名、事件处理的函数、一个布尔值。

    • 布尔值为true,表示在事件捕获阶段执行事件处理程序
    • 布尔值为false,表示在事件冒泡阶段执行事件处理程序
    • 若是不写布尔值,默认为false 示例:
    var button = document.getElementById('myButton')
    button.addEventListener('click', function(){
      alert('hello'+this.id)  
    }, false)
    复制代码

    和DOM0级事件处理程序同样,这个this.id打印仍是‘myButton’,其做用域仍然在依附的元素中。使用DOM2级事件处理程序的好处是能够添加多个事件,那么事件就会按照添加它们的顺序执行。

    经过addEventListener()添加的时间处理程序,只能经过removeEventListener()来删除。

    button.removeEventListener('click', function(){
      alert('hello'+this.id)  
    }, false)
    复制代码

    上面这样作是没有用的,由于removeEventListener(),须要传入同样的参数,表面上你确实参数传的同样,其实否则,里面有个匿名函数,因此你的第二参数永远都不会同样。

    var button = document.getElementById('myButton')
    var pomelo = function(){
      alert('hello'+this.id)  
    }
    button.addEventListener('click', pomelo, false)
    button.removeEventListener('click', pomelo, false)
    复制代码

    上面这样才是真正的删除了。

大多数状况下,都是将事件处理程序添加到事件流的冒泡阶段,若是不是特别的需求,建议添加到冒泡阶段。

相关文章
相关标签/搜索