发展历史
DOM 级别 0
DOM 级别 0 不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 Microsoft Internet Explorer 3.0 中的等价功能性的一种定义。
DOM 级别 1
DOM 级别 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。
DOM 级别 2
DOM 级别 2 对 DOM 级别 1 添加了样式表对象模型,并定义了操作附于文档之上的样式信息的功能性。 DOM 级别 2 同时还定义了一个事件模型(Events,规定了访问文档事件的 API),并提供了对 XML 命名空间的支持。
DOM 级别 3
DOM Level 3 规定了内容模型 (DTD 和 Schemas) 和文档验证。同时规定了文档加载和保存、文档查看、文档格式化和关键事件。
DOM0级
浏览器会把一些常用事件挂载到元素对象的私有属性上,让我们可以实现DOM0事件绑定。
DOM0级事件绑定通常有两种方式,一种是直接将事件处理程序作为html元素的属性值:
// 示例一
<div onclick="alert('点了我一下')">点击一下</div>
// 或
<div onclick="clickFn()">点击一下</div>
<script>
function clickFn(){
alert('点了我一下');
}
</script>
另一种是,通过js将事件处理程序添加到元素属性上:
// 示例二
<div>点击一下</div>
<script>
document.querySelector('div').onclick = clickFn;
function clickFn(){
alert('点了我一下');
}
</script>
DOM0级的事件监听,移除时只需将其属性设置为null即可。
需要注意的是:DOM0级的事件监听,只能为其指定一个事件处理函数,当指定了多个,后者会把前面的覆盖。
// 示例三
<button>点击一下</button>
<script>
document.querySelector('button').onclick = clickFn1;
document.querySelector('button').onclick = clickFn2;
function clickFn1(){
console.log('第一个')
};
function clickFn2(){
console.log('第二个')
}
</script>
点击button,打印结果如下:
DOM2级
DOM1级标准中并没有定义事件相关的内容,所以没有所谓的DOM1级事件模型。
在DOM2级中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的DOM2级事件模型。
DOM2级事件模型分为三个阶段:
- 捕获阶段:事件从Document对象沿着文档树向下传播给节点。如果目标的任何一个祖先专门注册了事件监听函数,那么在事件传播的过程中就会运行这些函数。(0级DOM事件模型处理没有捕获阶段)
- 目标阶段:下一个阶段发生在目标节点自身,直接注册在目标上的适合的事件监听函数将运行。(一般将此阶段看作冒泡阶段的一部分)
- 冒泡阶段:这个阶段事件将从目标元素向上传播回Document对象(与捕获相反的阶段)。虽然所有事件都受捕获阶段的支配,但并不是所有类型的事件都冒泡。
DOM2级事件绑定是使用addEventListener方法(IE使用attachEvent方法):
浏览器会给当前元素的某个事件行为开辟一个事件池(事件队列)【浏览器有一个统一的事件池,每个元素绑定的行为都放在这里,通过相关标志区分】,当我们通过addEventListener/attachEvent进行事件绑定的时候,会把绑定的方法放在事件池中;
当元素的某一行为被触发,浏览器回到对应事件池中,把当前放在事件池的所有方法按序依次执行;
// 示例四
<div>
<button>点击一下</button>
</div>
<script>
document.querySelector('button').addEventListener('click',clickBtn);
document.querySelector('div').addEventListener('click', bubbleDiv)
document.body.addEventListener('click', bubbleBody)
document.querySelector('div').addEventListener('click', captureDiv, true)
document.body.addEventListener('click', captureBody, true)
function clickBtn(){ console.log('click button'); }
function bubbleDiv(){ console.log('bubble div'); }
function bubbleBody(){ console.log('bubble body'); }
function captureDiv(){ console.log('capture div'); }
function captureBody(){ console.log('capture body'); }
</script>
点击button,其打印结果为:
使用addEventListener添加的事件监听,移除时需使用removeEventListener方法,且其参数需与addEventListener的参数完全一致!
// 在示例四的基础上添加如下代码片段
document.body.removeEventListener('click', captureBody, true)
再点击button,其打印结果为:
由以上结果看出,body在捕获阶段的点击事件处理函数captureBody被移除了。
与DOM0级不同的是,使用addEvenListener可以为当前元素的某一事件行为绑定多个不同方法,同样的,可以使用removeEventListener移除当前元素的某一事件行为的多个不同方法。
需要注意的是,事件处理函数若是匿名函数,则无法被移除!
// 示例五
<button>点击一下</button>
<script>
document.querySelector('button').addEventListener('click',clickBtn1);
document.querySelector('button').addEventListener('click',clickBtn2);
function clickBtn1(){ console.log('click button 1'); }
function clickBtn2(){ console.log('click button 2'); }
</script>
点击button,其打印结果为:
常用事件总结
鼠标事件
- click:当用户点击某个对象时
- contextmenu:当用户点击鼠标右键打开上下文菜单时
- dbclick:当用户双击某个对象时
- mousedown:当鼠标按钮被按下
- mouseenter:当鼠标指针移动到元素上时
- mouseleave:当鼠标指针移出元素时
- mousemove:当鼠标被移动时
- mouseover:当鼠标移动到某元素上时
- mouseout:当鼠标从元素移开
- mouseup:当鼠标按键被松开
键盘事件
- keydown:某个键盘按键被按下
- keypress:某个键盘按键被按下并松开
- keyup:某个键盘按键被松开
框架/对象事件
- abort:图像的加载被中断
- beforeunload:在即将离开页面(刷新或关闭)时触发
- error:在加载文档或图像时发生错误
- hashchange:该事件在当前URL的锚部分发生修改时触发
- load:一张页面或一副图像加载完成
- pageshow:在用户访问页面时触发
- pagehide:在用户离开当前网页跳转到另外一个页面时触发
- resize:窗口或框架被重新调整大小
- scroll:当文档被滚动时
- unload:用户退出页面
表单事件
- blur:元素失去焦点
- change:表单元素的内容发生改变时
- focus:元素获取焦点时
- focusin:元素即将获取焦点时
- focusout:元素即将失去焦点时
- input:获取用户输入时
- reset:表单重置时
- search:用户向搜索域输入文本时
- select:用户选取文本时
- submit:表单提交时
剪贴板事件
- copy:用户拷贝元素内容时
- cut:在用户剪切元素内容时
- paste:在用户粘贴元素内容时
打印事件
- afterprint:在页面已经开始打印,或者打印窗口已经关闭时触发
- beforeprint:在页面即将开始打印时触发
拖动事件
- drag:元素正在拖动时触发
- dragend:用户完成元素的拖动时触发
- dragenter:拖动的元素进入放置目标时触发
- deragleave:在拖动元素离开放置目标时触发
- dragover:在拖动元素在放置目标上时触发
- dragstart:在用户开始拖动元素时触发
- drop:在拖动元素放置在目标区域时触发