来源:http://qiqicartoon.com/?p=816
事件模型对于javascript程序员来说太重要了!如果你的javascript中找不到attahEvent或addEventListener的话,那我觉得真的有点太荒唐了(某些项目应该没有事件驱动)。
毫无疑问深入理解事件模型将使你的工作事半功倍!
其实理解事件模型倒也不是很困难,困难之处在于事件模型之前的兼容性!说到这里不得不提起讨厌的IE和喜爱的DOM。
我们知道IE内核的浏览器,它的事件模型是冒泡型事件,也就是说在IE内核下事件句柄的触发顺序是从ChildNode到ParentNode。
1 <div id="ancestor">
2 <button id="child">
3 Open the console and click me
4 </button>
5 </div>
以上的HTML代码在IE内核下,事件是这样传播的:
1、Button#child;
2、div#ancestor;
3、Body;
4、Document
切记!IE的内核是没有捕获事件过程的
那么在DOM标准的浏览器,事件传播的过程又是怎样的呢?我们依然拿上面的HTML代码做例子,在DOM标准的浏览器事件是这样传播的:
1、Window
2、Document
3、Body
4、Div#ancestor
5、Button#child
Bubble
6、Div#ancestor
7、Body
8、Document
9、Window
在DOM标准的浏览器中多了一个事件捕获过程,也就是说当开发者在一个无素上注册了事件后,这个事件的响应顺序是从window(最顶层)开始一级一级的向下传播,然后到了该元素后事件捕获过程结束,事件开如冒泡,一级一级向父层元素冒泡(请注意第6步)。当然了开发者可以很轻松的决定DOM标准的浏览器中的事件需要在哪个传播过程触发这。就需要谈一下事件的注册机制了。
DOM标准的浏览器事件注册方法是通过addEventListener方法注册,而IE内核的浏览器则是通过attachEvent方法注册。
这两个方法的区别,我在此简单的介绍下,若不太明白,可以自行去搜索相关资料。
addEventListener方法带有三个参数,分别是:eventType、handler、useCapture。
eventType不带有on字符串;
handler参数是一个事件句柄,这个函数或方法带有一个事件对象参数;
useCapture参数决定了事件句柄触发在哪种事件传播阶段,如果useCapture为true则为捕获阶段,反之则为冒泡阶段。
是不是还是不太理解捕获阶段和冒泡阶段,不用怕,看以下代码的演示:
我们依然用以上的HTML代码片段
1 var ancestorHandler = function (e){
2 //......
3 },
4 childHandler = function (e){
5 //......
6 };
7 document.querySelector('#ancestor').addEventListener('click',ancestorHandler,false);//注意第三个参数
8 document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数
以上代码我们为div节点注册了一个在冒泡阶段触发的事件句柄,为按钮节点注册了一个在捕获阶段的事件句柄,请注意DIV是按钮的父层。
当用户在这个DIV元素上点击时,事件的执行顺序是childHandler、ancestorHandler。
为什么会是这样呢?这是因为按钮的事件是在捕获阶段触发的,也就是从上到下,而DIV的事件是注册在冒泡阶段,也就是点击了这个按钮开始从这个按钮的位置往上冒泡。
当然了,我们可以阻止事件的冒泡,DOM事件对象提供了stopPropagation方法用于阻止事件流。
1 var ancestorHandler = function (e){
2 //......
3 },
4 childHandler = function (e){
5 e.stopPropagation();
6 //......
7 };
以上代码中我们在childHandler函数中添加了e.stopPropagation()代码片段,它将阻止事件流,事件流包括捕获阶段及冒泡阶段的事件流。
我们再修改上面的代码如下:
1 var ancestorHandler = function (e){
2 //......
3 },
4 childHandler = function (e){
5 //......
6 };
7 document.querySelector('#ancestor').addEventListener('click',ancestorHandler,true);//注意第三个参数
8 document.querySelector('#child').addEventListener('click',childHandler,true);//注意第三个参数
以上的代码产生的结果是:用户在DIV元素上单击时,将会依次触发ancestorHandler、childHandler函数,为什么?因为我们将div#ancestor的事件注册到捕获阶段了,也就是从上至下。当然了我们还可以阻止childHandler方法的执行。
1 var ancestorHandler = function (e){
2 e.stopPropagation();
3 //......
4 },
5 childHandler = function (e){
6 //......
7 };
以上代码将阻止按钮的事件触发。当用户点击了DIV的区域,仅仅触发ancestorHandler函数,因为我们阻止了事件流。
接下来我们看看在IE内核的浏览器中是如何注册事件的。IE内核提供了attachEvent方法为元素注册事件,注意该方法与DOM的addEventListener方法区别很大!该方法带有两个参数,
eventType 事件类型,请注意这个参数与addEventListener的eventType的区别,它必须带有on;
handler 事件句柄
请注意attachEvent没有提供事件捕获阶段的参数,IE内核的事件都是发生在冒泡阶段!
1 var ancestorHandler = function (e){
2 //......
3 },
4 childHandler = function (e){
5 //......
6 };
7 document.getElementById('ancestor').attachEvent('onclick',ancestorHandler);//注意没有第三个参数
8 document.getElementById('child').attachEvent('onclick',childHandler);//注意没有第三个参数
以上代码在IE中将为DIV元素和按钮元素注册了不同的事件。
另外还有一些注意事项:
1、DOM标准的addEventListener方法执行事件的顺序是按照事件注册的顺序执行的。而attachEvent方法则相反–后注册的事件先觖发,先注册的事件后触发。
2、DOM标准的浏览器文本节点也会冒泡,而IE内核的浏览器文本节点不会冒泡。
3、DOM标准的浏览器事件对象与IE内核的浏览器事件不同(具体请参阅http://www.quirksmode.org/js/introevents.html)。
4、DOM标准的浏览器事件卸载方式与IE内核的事件卸载方式不同。
1 object.removeEventListener(eventType,handler,useCapture);//DOM标准的事件卸载方式
2 object.detachEvent(eventType,handler);//IE内核的事件卸载方式
在DOM标准的事件卸载方式中需要注意的是:事件捕获的参数。如果你的事件是注册在捕获阶段,则卸载事件时,必须将其指定为捕获阶段(true),否则无法卸载;如果你的事件注册在注册在冒泡阶段,则必须将其指定为冒泡阶段(false),否则同样无法卸载!
分享到:
相关推荐
ECMAScript规范中的ECMA-357是与事件处理相关的一部分,它提供了JavaScript中处理事件的标准。 事件流是JavaScript事件模型的核心部分,描述了事件如何在DOM(Document Object Model)层次结构中传递。主要有两种...
了解并掌握"ie事件捕获控件"的相关技术,可以帮助开发者更深入地理解浏览器行为,提升Web应用的安全性和用户体验。同时,随着现代浏览器对标准支持的增强,类似的功能也可以应用到Firefox、Chrome等非IE浏览器上,...
在Internet Explorer(IE)浏览器中,DOM(文档对象模型)查看器是一个强大的工具,允许开发者和网页设计者深入理解网页结构,并对其进行交互式编辑。DOM是W3C标准,它将HTML或XML文档表示为一个树形结构,使我们...
本文将深入解析JavaScript中的事件捕获机制,并结合实际的例子讲解事件冒泡原理和不同浏览器(特别是IE和DOM标准)中的事件模型。 首先,我们需要理解什么是事件冒泡。事件冒泡是指当一个元素上的事件被触发后,该...
### JavaScrip文档对象模型(DOM)知识点详解 #### DOM简介 文档对象模型(Document Object Model,简称DOM)是一项由万维网联盟(W3C)制定的标准,旨在提供一种独立于编程语言的接口,使得开发者能够通过脚本语言...
最后,IE事件模型与DOM2模型有所不同,它不传递`event`对象给事件处理函数,而是将其作为全局`window`对象的属性。IE事件的传播模式仅包含DOM2的冒泡阶段和目标阶段,且仅能捕获鼠标事件。事件处理程序的注册和删除...
事件流描述了事件如何在DOM(文档对象模型)层次结构中传播。主要有两种类型:冒泡型事件流和捕获型事件流。冒泡型事件从最具体的元素(如按钮)开始,逐级向上至最不具体的元素(如document)传递。而捕获型事件则...
在深入理解这一机制前,我们需要了解三个关键术语:事件流、事件冒泡和事件捕获。 1. 事件流: 事件流描述了事件在HTML元素中传播的方式。根据DOM2级事件规范,事件流分为三个阶段:事件捕获阶段、处于目标阶段和...
JavaScript中的事件处理在不同的浏览器环境下,尤其是Internet Explorer (IE) 和遵循Document Object Model (DOM) 规范的浏览器之间存在显著差异。以下是这些差异的详细解释: 1. **事件流的区别**: - **IE冒泡型...
这里我们将深入探讨三种主要的事件绑定模型:内联模型、脚本模型和DOM2级事件模型。 1. **内联模型**: 这是最原始的事件处理方式,通过HTML元素的事件属性(如`onclick`)直接指定处理函数。例如: ```html ...
在W3C DOM模型中,`false`表示事件冒泡(event bubbling),`true`表示事件捕获(event capturing)。此外,`removeEventListener`可以用来解除事件绑定,以释放资源或改变事件处理行为。 这三种事件模型在实际开发...
在IT领域,尤其是在Web开发中,事件模型是一个关键的概念,用于处理用户与网页交互的响应。W3C DOM 2 Events 规范定义了事件模型,使得任何支持DOM的节点,如HTML元素,都可以成为EventTarget,即可以接收并处理事件...
5. **分析事件绑定**:在DOM树中,可以看到各个元素上绑定的事件处理函数,这对于理解和调试JavaScript事件逻辑非常有用。 6. **调试JavaScript**:配合IE的脚本调试器,可以在DOM Inspector中设置断点,查看变量值...
事件模型可以分为三种:原始事件模型(DOM0 级)、标准事件模型(DOM2 级)和 IE 事件模型(基本不用)。 原始事件模型的特点是绑定速度快,但由于绑定速度太快,可能页面还未完全加载出来,以至于事件可能无法正常...
**IE DOM Inspector** 是一款专为Internet Explorer浏览器设计的调试工具,它允许开发者和网页设计师在实时环境中查看、检查和修改网页的文档对象模型(DOM)。DOM是HTML和XML文档的一种结构化表示,通过DOM,我们...
为了确保代码的健壮性和跨浏览器兼容性,开发者需要对各种浏览器的事件处理机制有深入的理解,包括DOM0级、DOM2级事件处理以及IE特有事件模型。同时,通过持续实践和测试,可以避免这些低级错误,提高代码质量。在...