DOM事件级别是前端中比较常见的知识点,简单写一篇博客对这个知识点做个汇总。
为什么引入DOM级别
在 IE4 和 Netscape Navigator 4 支持不同形式的动态 HTML(DHTML)的情况下,开发者首先可以做到不刷新页面而修改页面外观和内容。这代表了 Web 技术的一个巨大进步,但也暴露了很大的问题。由于网景和微软采用不同思路开发 DHTML,开发者写一个 HTML 页面就可以在任何浏览器中运行的好日子就此终结。 为了保持 Web 跨平台的本性,必须要做点什么。人们担心如果无法控制网景和微软各行其是,那么 Web 就会发生分裂,导致人们面向浏览器开发网页。就在这时,万维网联盟(W3C,World Wide WebConsortium)开始了制定 DOM 标准的进程。
——出自《JavaScript高级程序设计》
DOM等级
常见的DOM事件等级有三种,分别为DOM Level 1、DOM Level 2以及DOM Level 3,对于不同等级的DOM,对应的DOM事件处理方式也是不同的。
DOM Level 0
不是说DOM事件等级有三种吗?可能有些人看晚上大部分文章都有写DOM Level 0,但是实际上并没有一个标准叫DOM Level 0,详细可以参考下面的引用:
在阅读关于 DOM 的资料时,你可能会看到 DOM Level 0 的说法。注意,并没有一个标准叫“DOM Level 0”,这只是 DOM 历史中的一个参照点。DOM Level 0 可以看作 IE4和 Netscape Navigator 4 中最初支持的 DHTML。
——出自《JavaScript高级程序设计》
所以上文的引用所提到的DOM Level 0指的是在DHTML中的这种写法:
|
|
常用的事件有下面这些:
- onload
- onunload
- onchange
- onsubmit
- onreset
- onselect
- onblur
- onfocus
- onkeydown
- onkeyup
- onkeydown vs onkeyup
- onkeypress
- onmouseover 和 onmouseout
- onclick
- ondblclick
- onmousedown 和 onmouseup
- onmousemove
不过这种写法有个致命缺陷,就是不能给一个元素添加多个点击事件,比如下面一个例子:
需求:给div
添加两个点击事件
如果使用DHTML中的写法
HTML&CSS:
|
|
JS:
|
|
现在点击页面上的div
元素,发现只会输出test2
,后面的事件会覆盖前面的事件,说明使用DHTML中的这种写法不能满足这个案例的需求,所以才会有了后面的DOM Level1,DOM Level2的标准。
如何解除事件绑定
对于这种写法如果要解除事件绑定,只需要把null
赋值给事件属性即可,对于所以对于上面的案例可以使用以下的写法即可解除引用:
div.onclick = null;
补充
对于这种写法的事件都是冒泡进行的,无法使用事件捕获。
DOM Level 1
1998 年 10 月,DOM Level 1 成为 W3C 的推荐标准。这个规范由两个模块组成:DOM Core 和 DOM HTML。前者提供了一种映射 XML 文档,从而方便访问和操作文档任意部分的方式;后者扩展了前者,并增加了特定于 HTML 的对象和方法(比如:JavaScript中的Document对象)。
——出自《JavaScript高级程序设计》
大家熟知的Node
,document
, document.createElement
都是在DOM1级别定义的,所以总结一下DOM Level 1的目标是映射文档结构,没有定义事件相关的内容,所以没有DOM Level 1对应的事件,这里就不做过多的讨论了。
DOM Level 2
DOM Level 1 的目标是映射文档结构,而 DOM Level 2 的目标则宽泛得多。这个对最初 DOM 的扩展增加了对(DHTML 早就支持的)鼠标和用户界面事件、范围、遍历(迭代 DOM 节点的方法)的支持,而且通过对象接口支持了层叠样式表(CSS)。另外,DOM Level 1 中的 DOM Core 也被扩展以包含对 XML 命名空间的支持。
——出自《JavaScript高级程序设计》
DOM Level 2引入了大量事件方法的支持,同时解决了DHTML的写法(DOM Level 0)中无法绑定多个处理函数的缺点,允许给一个元素添加多个处理函数。
DOM Level 2定义了addEventListener
方法,用于给对象绑定事件
语法:
EventTarget.addEventListener(EventType, callback, useCapture)
参数:
EventType
:事件类型callback
:事件处理的对应回调函数useCapture
:是否使用事件捕获,默认为false
,代表不使用
可以看到在DOM Level 2中可以使用事件捕获了,这也是相比DHTML的写法(DOM Level 0)中改动比较多的一个地方了。
如何解除事件绑定
在DOM Level 2定义了removeEventListener
方法,用于解除绑定的事件对象。
语法:
EventTarget.removeEventListener(EventType, listener, useCapture)
参数:
type
:要移除的事件类型listener
:要移除的函数useCapture
:指定需要移除的函数是否为捕获监听器
所以现在就可以针对DHTML的写法(DOM Level 0)的案例做一个修改,以便满足需求了,代码如下:
|
|
❕注意:如果给addEventListener
绑定的是一个匿名函数,会导致此事件无法解绑定。
DOM Level 3
DOM Level 3 进一步扩展了 DOM,增加了以统一的方式加载和保存文档的方法(包含在一个叫 DOM Load and Save 的新模块中),还有验证文档的方法(DOM Validation)。在 Level 3 中,DOM Core 经过扩展支持了所有 XML 1.0 的特性,包括 XML Infoset、XPath 和 XML Base。
——出自《JavaScript高级程序设计》
同时DOM Level 3中在DOM Level 2的基础上增加了更多事件的支持,详细的信息参考下面的的列表
事件 | 描述 |
---|---|
UI事件 | 当用户与页面上的元素交互时触发,如:load、scroll |
焦点事件 | 当元素获得或失去焦点时触发,如:blur、focus |
鼠标事件 | 当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup |
滚轮事件 | 当使用鼠标滚轮或类似设备时触发,如:mousewheel |
文本事件 | 当在文档中输入文本时触发,如:textInput |
键盘事件 | 当用户通过键盘在页面上执行操作时触发,如:keydown、keypress |
合成事件 | 当为IME(输入法编辑器)输入字符时触发,如:compositionstart |
变动事件 | 当底层DOM结构发生变化时触发,如:DOMsubtreeModified |
同时DOM3级事件也允许使用者自定义一些事件。
DOM Level 4
目前,W3C 不再按照 Level 来维护 DOM 了,而是作为 DOM Living Standard 来维护,其快照称为DOM4。DOM4 新增的内容包括替代 Mutation Events 的 Mutation Observers。
——出自《JavaScript高级程序设计》
详细请看 W3C DOM4
总结
- DOM Level 0
- 无法绑定多个事件
- 解除事件绑定将对象赋值为
null
即可 - 事件都是冒泡进行,无法改为事件捕获
- DOM Level 1
Node
,document
,document.createElement
都是在此时定义的- 添加了针对HTML的对象和方法,如
Document
对象
- DOM Level 2
- 定义了
addEventListener
与removeEventListener
两个方法,用于绑定事件与解除绑定(必须使用此方法解除绑定) - 使用
addEventListener
可以给一个对象同时绑定多个事件 - 可以通过
addEventListener
与removeEventListener
第三个参数去确定是在冒泡或者捕获阶段执行 - 匿名函数无法解除绑定
- 定义了
- DOM Level 3
- 添加了更多事件的支持
参考文献
- 《JavaScript高级程序设计》(第四版)
- 【SSD系列】DOM0, DOM1, DOM2, DOM3, DOM4,知多少
- DOM 事件机制
- 简述DOM 事件机制
- W3school-DHTML 教程