目前DOM标准有DOM1、DOM2、DOM3、DOM4,其中DOM4为草案,尚未推行,主要使用的是DOM3标准。
一、DOM1
DOM1分为DOM核心(Object Model Core)和HTML的DOM(Object Model HTML),DOM1是对DOM0的归纳整理概括,
DOM1支持的事件有:blur、click、focus、select这几个事件。
二、DOM2
DOM2包括DOM核心、视图、事件、样式、遍历范围和HTML。DOM2中的事件标准已经非常完善,在DOM3中并未对此进行修改,所以至今针对DOM的事件是以DOM2事件标准为基准的。
这里主要讲一下DOM Level2的事件标准。
在开始之前,来看一段代码:
以上的事件绑定,对于行内事件绑定B、C是正确的,对于JS代码中的事件绑定,事件一是正确的。
在行内绑定事件中,onclick=”要绑定的事件”,一旦用户点击,浏览器就eval(“要执行的代码”)。其中:eval("print")
只会将print方法打印出来。eval("print()")
会执行print()方法内的语句eval("print.call()")
的相当于eval(“print()”)
在JS代码中的事件绑定,一旦用户点击,那么浏览器就执行:x.onclick.call(this,arguments,{…})即点击后应该执行一个方法,x.onclick=print
直接将方法赋值到点击事件上,可执行y.onclick=print()
print()执行完无返回值,则返回undefined,所以此时y.onclick = undfined
,所以错误z.onclick=print.call()
同上
以上是DOM Level1的事件绑定方法,下面正式介绍DOM Level2的事件绑定
1、click事件绑定
1 | ...... |
addEventListener
绑定事件可以多次触发,先绑定先触发,后绑定后触发,执行顺序类似于栈的执行顺序,先进先出后进后出,即先定义先执行后定义后执行。
如果绑定多事件:1
2
3
4
5
6
7
8
9function f1(){
console.log(1);
}
function f2(){
console.log(2);
}
xxx.addEventListener('click',f1);
xxx.addEventListener('click',f2);
xxx.removeEventListener('click',f1); //移除事件
2、事件冒泡与捕获
1) 什么是事件
JavaScript
与HTML
之间的交互是通过事件
实现的。事件
,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。
2) 事件流
事件流
描述的是从页面中接收事件的顺序。但有意思的是,IE 和 Netscape 开发团队居然提出了差不多是完全相反的事件流的概念。IE 的事件流是事件冒泡流
,而 Netscape Communicator 的事件流是事件捕获流
。
事件冒泡
IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。以下面的 HTML 页面为例:1
2
3
4
5
6
7
8
9<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
当我们单击了页面中的div元素时,click事件的传播顺序为:<div>
-><body>
-><html>
->document
click事件首先会在div
元素上发生,而这个元素就是我们单击的元素。然后click事件沿着DOM树向上传播,在每一级节点上都会发生,直至传播到document
对象。如下图所示:IE9
、Firefox
、Chrome
和Safari
将事件一直 冒泡到window
对象。
事件捕获
Netscape Communicator 团队提出的另一种事件流叫做事件捕获(event capturing)。事件捕获
的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。如果仍以前面的 HTML 页面作为演示事件捕获的例子,那么单击<div>
元素就会以下列顺序触发 click 事件:document
-><html>
-><body>
-><div>
在事件捕获过程中,document
对象首先接收到 click 事件,然后事件沿 DOM 树依次向下,一直传播到事件的实际目标,即<div>
元素。事件捕获的过程如下图所示:
虽然事件捕获是 Netscape Communicator 唯一支持的事件流模型,但 IE9、Safari、Chrome、Opera 和 Firefox 目前也都支持这种事件流模型。尽管“DOM2 级事件”规范要求事件应该从 document 对象 开始传播,但这些浏览器都是从 window 对象开始捕获事件的。
由于老版本的浏览器不支持,因此很少有人使用事件捕获。
3)DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段
、处于目标阶段
和事件冒泡阶段
。首 先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶 段,可以在这个阶段对事件做出响应。以前面简单的 HTML 页面为例,单击<div>
元素会按下图所示顺序触发事件。
在 DOM 事件流中,实际的目标(<div>
元素)在捕获阶段不会接收到事件。这意味着在捕获阶段事件从 document
到<html>
再到<body>
后就停止了。下一个阶段是“处于目标”阶段,于是事件在 <div>
上发生,并在事件处理(后面将会讨论这个概念)中被看成冒泡阶段的一部分。然后,冒泡阶段发生, 事件又传播回文档。
4)例子
1 | //结构,默认已经引入jQuery |
- 本文主要参考《JavaScript高级程序设计》第13章