JavaScript应用核心:事件处理概述(1)
事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水。当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了。
事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是Web浏览器中发生的事情,比如说某个Web页面加载完成,或者是用户滚动窗口或改变窗口大小。
51CTO推荐阅读:详解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树最顶层元素一直到最精确的元素,这个事件模型对于开发者来说(至少是我..)有点费解,因为直观上的理解应该如同冒泡型,事件传递应该由最确定的元素,即事件产生元素开始。
DOM标准的事件模型
我们已经对上面两个不同的事件模型进行了解释和对比。DOM标准同时支持两种事件模型,即捕获型事件与冒泡型事件,但是,捕获型事件先发生。两种事件流都会触发DOM中的所有对象,从document对象开始,也在document对象结束(大部分兼容标准的浏览器会继续将事件是捕捉/冒泡延续到window对象)。
DOM标准的事件模型最独特的性质是,文本节点也会触发事件(在IE不会)。
事件传送
为了更好的说明DOM标准中的事件流原理,我们把它放在“事件传送”小结里来更具体的解释。
显然,如果为一个超链接添加了click事件监听器,那么当该链接被点击时该事件监听器就会被执行。但如果把该事件监听器指派给了包含该链接的p元素或者位于DOM树顶端的document节点,那么点击该链接也同样会触发该事件监听器。
这是因为事件不仅仅对触发的目标元素产生影响,它们还会对沿着DOM结构的所有元素产生影响。这就是大家所熟悉的事件转送。W3C事件模型中明确地指出了事件转送的原理。事件传送可以分为3个阶段。
(1).在事件捕捉(Capturing)阶段,事件将沿着DOM树向下转送,目标节点的每一个祖先节点,直至目标节点。例如,若用户单击了一个超链接,则该单击事件将从document节点转送到html元素,body元素以及包含该链接的p元素。在此过程中,浏览器都会检测针对该事件的捕捉事件监听器,并且运行这件事件监听器。
(2)在目标(target)阶段,浏览器在查找到已经指定给目标事件的事件监听器之后,就会运行 该事件监听器。目标节点就是触发事件的DOM节点。例如,如果用户单击一个超链接,那么该链接就是目标节点(此时的目标节点实际上是超链接内的文本节点)。
(3).在冒泡(Bubbling)阶段,事件将沿着DOM树向上转送,再次逐个访问目标元素的祖先节点到document节点。该过程中的每一步。浏览器都将检测那些不是捕捉事件监听器的事件监听器,并执行它们。
并非所有的事件都会经过冒泡阶段的
所有的事件都要经过捕捉阶段和目标阶段,但是有些事件会跳过冒泡阶段。例如,让元素获得输入焦点的focus事件以及失去输入焦点的blur事件就都不会冒泡。






