DOM事件模型或DOM事件机制

127 阅读2分钟

首先举例一个点击事件

代码段A:

<div id='grandfather'>
    <div id='father'>
        <div id='son'></div>
    </div>
</div>

现在有三个div,我在三个div上都绑定点击事件click,请问?是谁触发click事件了?
答案是都触发。
但是又有一个问题,谁先触发click事件?
有两个顺序:

  1. grandfather => father => son
  2. son => father => grandfather 在以前,IE5和网景公司就遇到这个问题,并且争论了一番,最后由W3C制定了标准才定论。、

一.W3C标准

  1. 2002年,W3C发布标准《DOM Level 2 Events Specification》。
  2. 它规定浏览器应该同时支持两种调用顺序
  3. 首先按照爷爷=>爸爸=>儿子的顺序看有没有函数监听,然后按照儿子=>爸爸=>爷爷顺序看有没有函数监听。
  4. 有监听函数就调用,并提供事件信息,没有就跳过。
  5. 开发者可以选择将监听函数放在捕获阶段还是冒泡阶段。

二.事件捕获和事件冒泡

1.定义

  1. 从外向内找监听函数,叫事件捕获
  2. 从内向外找监听函数,叫事件冒泡

2.图解

image.png

三.事件绑定函数:addEventListener

1.事件绑定API

IE5以上系列:div.attachEvent('onclick',fn)//冒泡
网景: div.addEventListener('onclick',fn)//捕获
W3C: div.addEventListener('onclick',fn,bool)

现在默认使用W3C: div.addEventListener('onclick',fn,bool)

  1. 如果bool不传或者为false,那么就让fn在冒泡阶段浏览器调用(默认)
  2. 如果bool为true,那么就让fn在捕获阶段被浏览器被调用

2.图解

image.png

四.target和currentTarget的区别

  1. e.target是用户操作的元素
  2. e.currentTarget是浏览器监听的元素 举例代码:
<div id='ctclick'>
    <span id='tclick'>click<span/>
<div/>

在事件监听上,浏览器监听的是div,操作的元素是span。
还是不理解可以查看MDN上的targetcurrentTarget的不同。

五.一个特例

1.特例

只有一个div被监听,并且fn分别在捕获阶段和冒泡阶段监听点击事件

2.解决方案

div.addEventListener('click',f1,true)//捕获
div.addEventListener('click',f2,true)//冒泡
  1. 问题:请问f1先执行还是f2先执行?
  2. 答案:f1先执行
  3. 原因:谁先监听谁先执行

六.取消冒泡

  1. 捕获阶段不能取消监听,但冒泡阶段可以取消监听
  2. e.stopPropagation()放在监听函数中,一般情况下可中断冒泡,使得浏览器不再向上走
  3. 所有的冒泡都能被取消

7.不可阻止默认动作

  1. 默认动作有的可以取消有的不能取消
  2. 查看这个信息的方法:在浏览器中搜MDN 关键词 event,并在MDN的英文版中查看
  3. MDN搜索scroll event,看到BubblesCancelable.Bubbles的意思是该事件是否冒泡。Cancelable的意思是是否支持开发者可以阻止默认动作,与冒泡无关.

参考资料:DOM事件机制 作者:人生没有什么过不去的