DOM 是针对HTML和XML文档定义的一个API, DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。DOM脱胎于
Netscape
及微软公司创始的DHTML(动态HTML)
, 但现在它已经成为表现和操作页面标记的真正的跨平台、语言的中立的方式。
发展
- dom0:
主要定义了HTML和XML文档的底层结构。在DOM0中,DOM由两个模块组成:DOM Core(DOM核心)和DOM HTML。 - dom2:
- DOM视图(DOM Views):定义了跟踪不同文档视图的接口
- DOM事件(DOM Events):定义了事件和事件处理的接口
- DOM样式(DOM Style):定义了基于CSS为元素应用样式的接口
- DOM遍历和范围(DOM Traversal and Range):定义了遍历和操作文档树的接口
- dom3:
- DOM加载和保存模块(DOM Load and Save):引入了以统一方式加载和保存文档的方法
- DOM验证模块(DOM Validation):定义了验证文档的方法
- DOM核心的扩展(DOM Style):支持XML 1.0规范,涉及XML Infoset、XPath和XML Base
DOM2级和3级的目的在于扩展DOM API以满足操作XML的所有需求同时提供更好的错误处理及特性检测能力
事件对象
- DOM中的事件对象
- IE中的事件对象
可以看出还是有很大差别的,因此未来做到兼容,可以像类似下面这个函数
1 | var EventUtil = { |
事件处理
- DOM0级事件处理: dom0级事件会覆盖,即只能添加一个事件
将一个函数赋值给一个事件处理程序属性。简单且具有跨浏览器优势。
1 | var btn = document.getElementById('btn'); |
- DOM2级事件处理程序:定义了两个方法,好处是可以添加多个事件处理程序。
addEventListener()
只能用下面的方法移除removeEventListener()
1 | btn.addEventListener('click', function(){ |
如果给一个body中的子节点同时注册冒泡和捕获事件,事件触发会按注册的顺序执行
event.stopImmediatePropagation
和
-
event.stopImmediatePropagation
作用在当前节点以及事件链上的所有后续节点上,目的是在执行完当前事件处理程序之后,停止当前节点以及所有后续节点的事件处理程序的运行 -
stopPropagation
的在执行完绑定到当前元素上的所有事件处理程序之后,停止执行所有后续节点的事件处理程序 -
IE事件处理程序: 均添加到冒泡阶段
attachEvent()
detachEvent()
1 | btn.attachEvent('onclick', function() { |
注意和dom0级和dom2级事件处理程序的区别在于作用域。以及在添加多个事件处理程序时不是按顺序执行,而是以相反的顺序执行。(这里的顺序是《JavaScript高级程序设计》中的,但是经过实验发现ie10,ie9是按顺序的,而ie8以下才按相反顺序)
注意:只有DOM2级事件规定事件包括三个阶段:
1. 事件捕获阶段
2. 处于目标阶段
3. 事件冒泡阶段
例子:
1 | <body> |
区别总结
-
dom0级
- 只能在冒泡阶段触发
- 只能绑定一个事件函数
- 事件函数this 指向被点击的元素本身
- 通过置空onclick属性解绑事件
-
dom2级事件
- 非ie:
- 可绑定多个事件函数
- 事件函数this 指向被点击的元素本身
- 多个事件函数的书法顺序和绑定顺序一样
- ie
- 事件函数this属性引用全局对象,因此要用 window.event
- 多个事件函数的书法顺序和绑定顺序相反
- 非ie:
-
dom3级事件:
规定了以下几种事件:- UI事件当用户与页面上的元素交互时触发
- 焦点事件当元素获得或者失去焦点时触发
- 鼠标事件当用户通过鼠标在页面上执行操作时触发
- 滚轮事件当使用鼠标滚轮或类似设备时触发
- 文本事件当在文档中输入文本时触发
- 键盘事件当用户通过键盘在页面上执行操作时触发
- 合成事件当为IMEInput Method Editor输入法编辑器输入字符时触发
- 变动事件当底层Dom结构发生变化时触发
- 定义了自定义事件自定义事件不是由DOM原生触发的它的目的是让开发人员创建自己的事件
事件委托(代理)
事件委托利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
- 优点:
- 提高document对象访问效率
- 在页面中事件处理程序所花的时间少
- 整个页面占用内存空间更少,能够提高整体性能。
- 动态添加的元素无需额外注册事件。
- 删除的元素无需注销事件,因为一般如果元素注册了事件删除后需手动删除以回收内存
- 缺点(局限)
- 事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时
- 只能用于会冒泡的事件中,比如focus和blur本身是不会冒泡的
- mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
1 | <div id="box"> |
1 | window.onload = function(){ |
参考: