本节目录
一、事件流
在单击按钮的同时,你也单击了按钮的容器元素,甚至也单击了整个页面。事件流描述的是从页面中接收事件的顺序。
1.1 事件冒泡
所有现代浏览器都支持事件冒泡(从内到外),事件冒泡即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。以下面的 HTML
页面为例:
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
如果你单击了页面中的<div>
元素,那么这个click
事件会按照如下顺序传播:
(1) <div>
(2) <body>
(3) <html>
(4) document
也就是说,click
事件首先在<div>
元素上发生,而这个元素就是我们单击的元素。然后,click
事件沿 DOM
树向上传播,在每一级节点上都会发生,直至传播到document
对象。
1.2 事件捕获
事件捕获的思想是从外到内。事件捕获的用意在于在事件到达预定目标之前捕获它。如果仍以前面的HTML
页面作为演示事件捕获的例子,那么单击<div>
元素就会以下列顺序触发click
事件。
(1) document
(2) <html>
(3) <body>
(4) <div>
在事件捕获过程中,document
对象首先接收到 click
事件,然后事件沿DOM
树依次向下,一直传播到事件的实际目标,即<div>
元素。
1.3 事件捕获机制
事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。以前面简单的HTML
页面为例,单击<div>
元素会按照下图所示顺序触发事件。
在DOM
事件流中,实际的目标(<div>元素)
在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从 document
到<html>
再到<body>
后就停止了。下一个阶段是“处于目标”阶段,于是事件在<div>
上发生,并在事件处理中被看成冒泡阶段的一部分。然后,冒泡阶段发生,事件又传播回文档。
IE9、Opera、Firefox、Chrome 和Safari 都支持DOM 事件流;IE8 及更早版本不支持DOM 事件流。
二、事件处理程序
诸如click
、load
和 mouseover
,都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以"on"
开头,因此click
事件的事件处理程序就是 onclick
,load
事件的事件处理程序就是 onload
。
2.1 HTML 事件处理
通过event
变量,可以直接访问事件对象
<!-- 输出 "click" -->
<input type="button" value="Click Me" onclick="alert(event.type)">
在这个函数内部,this
值等于事件的目标元素
<!-- 输出 "Click Me" -->
<input type="button" value="Click Me" onclick="alert(this.value)">
下面这行代码与前面的例子效果相同
<!-- 输出 "Click Me" -->
<input type="button" value="Click Me" onclick="alert(value)">
事件处理程序无需引用表单元素就能访问其他表单字段
<!-- 输出 "My Name" -->
<form method="post">
<input type="text" name="username" value="My Name">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
原因是在这个函数内部,使用with
像下面这样扩展作用域:
function(){
with(document){
with(this){
//元素属性值
}
}
}
// 如果当前元素是一个表单输入元素,则作用域中还会包含访问表单元素(父元素)的入口
function(){
with(document){
with(this.form){
with(this){
//元素属性值
}
}
}
}
//这样扩展作用域的方式,可以让事件处理程序无需引用表单元素就能访问其他表单字段
在HTML
中指定事件处理程序存在一个时差问题。因为用户可能会在HTML
元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。
以下面例子为例:
<input type="button" value="Click Me" onclick="showMessage()" />
<script type="text/javascript