DOM事件机制

144 阅读2分钟

DOM

首先,DOM全称是Document Object Model,即文档对象模型。DOM是W3C的标准,定义了访问 HTML 和 XML 文档的标准。

DOM事件

事件是用户或者浏览器自己执行的某种动作,是文档或者浏览器发生的一些交互瞬间,比如点击(click)按钮等,这里的click就是事件的名称。JS与html之间的交互是通过事件实现的,DOM支持大量的事件。

DOM事件机制(事件流)

DOM的结构是一个树形,每当HTML元素产生事件时,该事件就会在树的根节点和元素节点之间传播,所有经过的节点都会收到该事件。DOM事件流的出现是在DOM节点中事件发生时常见的一种现象中产生的,如下问题

<div class="爷爷" onclick="console.log('我是爷爷')">
      <div class="爸爸" onclick="console.log('我是爸爸')">
            <div class="儿子" onclick="console.log('我是儿子')">
                  文字
            </div>
      </div>
</div>

//1. 点击了“文字”后,算不算点击了儿子?算不算点击了“爸爸”,算不算点击了“爷爷”?
//   答案是都算,点击元素内部的任一元素节点,都算点击了该元素。这就涉及到一个事件流的问题

在“浏览器大战”时微软的IE浏览器就是按照由内向外的事件流顺序定义DOM事件流的。但是和其对立的网景公司却是反着定义的,网景公司的DOM事件流传递顺序是由外层向内层执行,先执行爷爷的,再执行爸爸的,最后执行儿子的,后来W3C统一了DOM事件机制的标准,

  • 文档名位DOM level2 Events Specification
  • 规定浏览器同时支持两种调用顺序
  • 首先 按爷爷->爸爸->儿子 顺序看有没有函数监听
  • 然后 按儿子->爸爸->爷爷 顺序看有没有函数监听
  • 有监听函数就调用,并提供事件信息,没有就跳过

术语

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

开发者可以自己选择在冒泡阶段还是捕获阶段执行监听,示意图:

addEventListener

事件绑定API

  • IE5*:baba.attachEvent('onclick',fn)//冒泡
  • 网景:baba.addEventListener('click',fn) //捕获
  • W3C:baba.addEventListener('click',fn,bool)

如果bool不传或传false,则在冒泡阶段执行baba的监听函数fn,并提供事件信息;如果bool为ture,则在捕获阶段发现baba有fn监听函数,就会调用fn,并提供事件信息,你可以选择把fn放在哪边:

补充: 一般情况下,如果在捕获阶段和冒泡阶段都有对应的事件处理函数,一般是先执行捕获,再执行冒泡。但是如果只有一个div被监听时,对其来说,捕获和冒泡是同级的,因此会按照其代码顺序,谁先注册先执行。 捕获不可以取消,冒泡可以取消。取消冒泡:e.stopPropagation()。