日期:2014-05-16  浏览次数:20342 次

理解JavaScript中的事件处理

理解JavaScript中的事件处理

这篇文章对于了解Javascript的事件处理机制非常好,将它全文转载于此,以备不时之需。

什么是事件?

事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水。当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是 Web 浏览器中发生的事情,比如说某个 Web 页面加载完成,或者是用户滚动窗口或改变窗口大小。

通过使用 JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。

今天的事件

在漫长的演变史,我们已经告别了内嵌式的事件处理方式(直接将事件处理器放在 HTML 元素之内来使用)。今天的事件,它已是DOM的重要组成部分,遗憾的是, IE继续保留它最早在IE4.0中实现的事件模型,以后的IE版本中也没有做太大的改变,这也就是说IE还是使用的是一种专有的事件模型(冒泡型),而其 它的主流浏览器直到DOM 级别 3 规定定案后,才陆陆续续支持DOM标准的事件处理模型 — 捕获型与冒泡型。

历史原因是: W3C 规范 在DOM 级别 1中并没有定义任何的事件,直到发布于 2000 年 11 月 的DOM 级别 2 才定义了一小部分子集,DOM 级别 2中已经提供了提供了一种更详细的更细致的方式以控制 Web 页面中的事件,最后,完整的事件是在2004年 DOM 级别 3的规定中才最终定案。因为IE4是1995推出的并已实现了自己的事件模型(冒泡型),当时根本就没有DOM标准,不过在以后的DOM标准规范过程中已 经把IE的事件模型吸收到了其中。

目前除IE浏览器外,其它主流的Firefox, Opera,
Safari都支持标准的DOM事件处理模型。IE仍然使用自己专有的事件模型,即冒泡型,它事件模型的一部份被DOM标准采用,这点对于开发者来说也是有好处的,只有使用
DOM标准,IE都共有的事件处理方式才能有效的跨浏览器。

DOM事件流

DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事件,这个传播过程可称为DOM事件流。

事件顺序有两种类型:事件捕捉事件冒泡

冒泡型事件(Event Bubbling)

这是IE浏览器对事件模型的实现,也是最容易理解的,至少笔者觉得比较符合实际的。冒泡,顾名思义,事件像个水中的气泡一样一直往上冒,直到顶端。从
DOM树型结构上理解,就是事件由叶子节点沿祖先结点一直向上传递直到根节点;从浏览器界面视图HTML元素排列层次上理解就是事件由具有从属关系的最确 定的目标元素一直传递到最不确定的目标元素.冒泡技术.冒泡型事件的基本思想,事件按照从特定的事件目标开始到最不确定的事件目标.

捕获型事件(Event Capturing)

Netscape 的实现,它与冒泡型刚好相反,由DOM树最顶层元素一直到最精确的元素,这个事件模型对于开发者来说(至少是我..)有点费解,因为直观上的理解应该如同冒泡型,事件传递应该由最确定的元素,即事件产生元素开始。

?

event-buddle

DOM标准的事件模型

我们已经对上面两个不同的事件模型进行了解释和对比。DOM标准同时支持两种事件模型,即捕获型事件冒泡型事件 ,但是,捕获型事件先发生。两种事件流都会触发DOM中的所有对象,从document对象开始,也在document对象结束(大部分兼容标准的浏览器会继续将事件是捕捉/冒泡延续到window对象)。

domevent

如图:首先是捕获式传递事件,接着是冒泡式传递,所以,如果一个处理函数既注册了捕获型事件的监听,又注册冒泡型事件监听,那么在DOM事件模型中它就会被调用两次。

DOM标准的事件模型最独特的性质是,文本节点也会触发事件(在IE不会)。

capturing-bubbling

事件传送

为了更好的说明DOM标准中的事件流原理,我们把它放在“事件传送”小结里来更具体的解释。

显然,如果为一个超链接添加了click事件监听器,那么当该链接被点击时该事件监听器就会被执行。但如果把该事件监听器指派给了包含该链接的p元 素或者位于DOM树顶端的document节点,那么点击该链接也同样会触发该事件监听器。这是因为事件不仅仅对触发的目标元素产生影响,它们还会对沿着 DOM结构的所有元素产生影响。这就是大家所熟悉的事件转送

W3C事件模型中明确地指出了事件转送的原理。事件传送可以分为3个阶段。

Standard-event-propagation

如图:标准的事件转送模式

(1).在事件捕捉(Capturing)阶段,事件将沿着DOM树向下转送,目标节点的每一个祖先节点,直至目标节点。例如,若用户单击了一个超链接,则该单击事件将从document节点转送到html元素,body元素以及包含该链接的p元素。

在此过程中,浏览器都会检测针对该事件的捕捉事件监听器,并且运行这件事件监听器。

(2). 在目标(target)阶段,浏览器在查找到已经指定给目标事件的事件监听器之后,就会运行 该事件监听器。目标节点就是触发事件的DOM节点。例如,如果用户单击一个超链接,那么该链接就是目标节点(此时的目标节点实际上是超链接内的文本节点)。

(3).在冒泡(Bubbling)阶段,事件将沿着DOM树向上转送,再次逐个访问目标元素的祖先节点到document节点。该过程中的每一步。浏览器都将检测那些不是捕捉事件监听器的事件监听器,并执行它们。

并非所有的事件都会经过冒泡阶段的

所有的事件都要经过捕捉阶段和目标阶段,但是有些事件会跳过冒泡阶段。例如,让元素获得输入焦点的focus事件以及失去输入焦点的blur事件就都不会冒泡。

?

事件句柄和事件接听器

事件句柄

事件句柄(又称事件处理函数,DOM称之为事件监听函数),用于响应某个事件而调用的函数称为事件处理函数
。每一个事件均对应一个事件句柄,在程序执行时,将相应的函数或语句指定给事件句柄,则在该事件发生时,浏览器便执行指定的函数或语句,从而