`
shangjava
  • 浏览: 1229442 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

理解DOM事件流

阅读更多

DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有着相当大的影响。这两种事件流分别是捕获和冒泡。和许多Web技术一样,在它们成为标准之前,Netscape和微软各自不同地实现了它们。Netscape选择实现了捕获事件流,微软则实现了冒泡事件流。幸运的是,W3C决定组合使用这两种方法,并且大多数新浏览器都遵循这两种事件流方式。

默认情况下,事件使用冒泡事件流,不使用捕获事件流。然而,在Firefox和Safari里,你可以显式的指定使用捕获事件流,方法是在注册事件时传入useCapture参数,将这个参数设为true。下面用个例子分别来测试这两种事件流。

1、冒泡事件流
当事件在某一DOM元素被触发时,例如用户在客户名字节点上点击鼠标,事件将跟随着该节点继承自的各个父节点冒泡穿过整个的DOM节点层次,直到它遇到依附有该事件类型处理器的节点,此时,该事件是onclick事件。在冒泡过程中的任何时候都可以终止事件的冒泡,在遵从W3C标准的浏览器里可以通过调用事件对象上的stopPropagation()方法,在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播,事件将一直通过DOM冒泡直至到达文档根。

测试的HTML文件,其中用到了mootools-release-1.11.js,对mootools的代码进行了改动:
addListener:function(type,fn,setCapture)...{
if(this.addEventListener)this.addEventListener(type,fn,setCapture);
else...{
this.attachEvent('on'+type,fn);
if(setCapture)this.setCapture(true);
}

returnthis;
}

给addListener方法里增加了setCapture参数,用于测试捕获事件流。
<body>
<divid="dd1-ct"style="width:400px;height:400px;border:1pxsolid#999;padding:2px">Container
<divid="dd1-item1"style="width:200px;height:200px;border:1pxsolid#999;padding:2px">Item1
<divid="dd1-item2"style="width:100px;height:100px;border:1pxsolid#999;padding:2px">Item2</div>
</div>
</div>
<divid='rh'></div>
</body>

效果:

js:
fn1=function(e)...{
//e.stopPropagation();
$('rh').innerHTML+='Item1clicked!******';
}
;

fn2
=function(e)...{
//e.stopPropagation();
$('rh').innerHTML+='Item2clicked!-------';
}
;

fn
=function(e)...{
//e.stopPropagation();
$('rh').innerHTML+='Containerclicked!&&&&&&&&';
}
;

$(
'dd1-item2').addListener('click',fn2.bindWithEvent(),false);
$(
'dd1-item1').addListener('click',fn1.bindWithEvent(),false);
$(
'dd1-ct').addListener('click',fn.bindWithEvent(),false);


测试结果ie和ff下效果一致:单击item2,会依次触发fn2、fn1、fn;单击item1,会依次触发fn1、fn;单击Container,只会触发fn;当在任何一个事件处理器里调用e.stopPropagation();都会阻止事件的冒泡。

2、捕获事件流
事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事件目标元素之间各个继承派生的元素所捕获,如果事件监听器在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何元素以对事件做出处理;否则,事件会被接着传递给派生元素路径上的下一元素,直至目标元素。事件到达目标元素后,它会接着通过DOM节点再进行冒泡。

这里ie与ff存在着很大的差异,甚至ie6与ie7的表现也各不相同,所以分开测试。

a、ff
事件从从DOM层次的根开始往下传递时,会被useCapture属性为true的事件监听器所捕获,而到达目标元素再从目标元素冒泡时,则会被useCapture属性为false的事件监听器所捕获。当在任何一个事件处理器里调用e.stopPropagation();都会阻止事件的传播。

b、ie6
用事实说话:

第一种情况:
$('dd1-item2').addListener('click',fn2.bindWithEvent(),true);
$(
'dd1-item1').addListener('click',fn1.bindWithEvent(),true);
$(
'dd1-ct').addListener('click',fn.bindWithEvent(),true);

单击浏览器的任何位置,都只是触发fn;

第二种情况:
$('dd1-item2').addListener('click',fn2.bindWithEvent(),true);
$(
'dd1-item1').addListener('click',fn1.bindWithEvent(),true);
$(
'dd1-ct').addListener('click',fn.bindWithEvent(),false);

单击浏览器的任何位置,会依次触发fn1、fn;

第三种情况:
$('dd1-item2').addListener('click',fn2.bindWithEvent(),true);
$(
'dd1-item1').addListener('click',fn1.bindWithEvent(),false);
$(
'dd1-ct').addListener('click',fn.bindWithEvent(),false);

单击浏览器的任何位置,会依次触发fn2、fn1、fn;

结论:如果HTML元素捕获了通过该元素的setCapture()方法对这个元素的设置,依附于该元素的处理器将会被事件触发,即使setCapture()方法被调用的这个元素不在目标元素的祖先路径中。事实上你甚至单击浏览器的非页面部分都会触发事件处理器。并且事件一旦被捕获就不会继续再往下传播(即使该元素在目标元素的祖先路径中),而是立刻冒泡。e.stopPropagation();会阻止事件的冒泡。

c、ie7
测试效果与冒泡事件流一致。将对捕获事件流的支持干掉了?

结论:正如mootools所做的,避免捕获事件流。
分享到:
评论

相关推荐

    dom4j基于事件流解析大XML的文件 示例

    而DOM4J提供了一种基于事件流的解析方式,即SAX解析器,可以有效地解决这个问题。 **DOM4J解析XML的优势:** 1. **灵活性**:DOM4J提供了丰富的接口和方法,支持XPath查询,可以方便地进行XML结构的操作。 2. **...

    DOM事件的区别

    本文将从DOM0级事件处理、DOM2级事件处理以及事件流、事件委托等方面进行深入探讨,帮助读者更好地理解这些概念及其区别。 #### 一、DOM0级事件处理 DOM0级事件处理是最基础的JavaScript事件处理模型,它允许...

    深入理解JS DOM事件机制

    在深入理解这一机制前,我们需要了解三个关键术语:事件流、事件冒泡和事件捕获。 1. 事件流: 事件流描述了事件在HTML元素中传播的方式。根据DOM2级事件规范,事件流分为三个阶段:事件捕获阶段、处于目标阶段和...

    JavaScript事件学习小结(一)事件流

    总结,JavaScript事件流是理解DOM中事件处理的关键,它决定了事件处理程序何时以及如何被调用。了解事件流有助于优化事件处理,避免不必要的事件处理和提高性能。通过合理利用事件流,开发者可以创建更加高效和用户...

    吉威 GEOWAY-CIPS-DOM工作流操作步骤

    本文将详细解析GEOWAY-CIPS在DOM工作流中的具体操作步骤,以帮助用户更好地理解和应用这一流程。 1. 数字地面模型(DEM)的预处理: 在处理DOM之前,通常需要对DEM进行预处理。当存在多个DEM镶嵌时,首先进行单...

    HTML DOM 参考手册 电子书

    8. **DOM事件和事件流**:事件流描述了事件在DOM中的传播路径,包括捕获阶段、目标阶段和冒泡阶段。理解事件流可以帮助我们更有效地处理事件。 9. **DOM与JavaScript的结合**:DOM是JavaScript与HTML交互的核心,书...

    DOM.zip_HTML dom_zip

    1. **DOM定义**:理解DOM是什么,它是如何工作的,以及为什么它对于网页动态交互和数据操作至关重要。 2. **DOM结构**:学习DOM树的构建方式,包括元素节点、属性节点、文本节点等不同类型的节点,以及它们之间的...

    DOM.zip_JavaScript dom_it

    8. **DOM事件流**:DOM事件流描述了事件如何在元素层级上传播,分为捕获阶段、目标阶段和冒泡阶段,开发者可以据此控制事件处理顺序。 9. **DOM性能优化**:尽管DOM操作强大,但频繁的操作可能导致性能下降。因此,...

    dom4j-2.1.3.zip

    另一份重要的资源是"dom4j-2.1.3-sources.jar",它提供了DOM4J库的源代码,允许开发者深入研究DOM4J的内部实现,对于理解DOM4J的工作原理、进行扩展或者调试都是不可或缺的。通过阅读源代码,开发者可以学习到如何...

    dom4j_1.6.1.jar dom4j_2.1.0.jar

    7. **源码和文档**:拥有源码意味着开发者可以深入理解DOM4J的工作机制,对问题进行调试和定制。文档通常包含API参考、教程和示例,是学习和使用库的重要资源。 8. **版本差异**:从1.6.1到2.1.0,DOM4J可能进行了...

    dom,jdom,dom4j的区别

    在选择DOM、SAX、JDOM或DOM4J时,主要考虑以下几个因素:1) 对性能的需求,大型文档可能更适合SAX或DOM4J的流处理模式;2) 对编程简便性的要求,DOM和JDOM通常更容易上手,而SAX需要编写更多的事件处理代码;3) 是否...

    javascript dom2 源码及pdf

    在JavaScript DOM2中,事件处理分为两个级别:事件目标和事件流。事件目标是指事件实际发生的地方,而事件流包括冒泡和捕获两种模式。你可以通过`addEventListener()`和`removeEventListener()`方法来添加和移除事件...

    JavaScript & DOM Enlightenment

    DOM Enlightenment可能涵盖了如何通过JavaScript访问和修改DOM节点,包括元素选择(如querySelector和querySelectorAll)、遍历DOM树、添加和删除元素、以及事件处理。此外,还可能涉及到性能优化技巧,如使用文档...

    javascript_DOM操作.rar

    8. **DOM事件流**:DOM事件流包括捕获阶段、目标阶段和冒泡阶段。理解这个过程对于有效处理事件至关重要。 9. **事件委托**:利用事件冒泡,可以在父元素上设置监听器处理子元素的事件,减少内存消耗和代码冗余。 ...

    JavaScrpt DOMscripting编程艺术

    8. **DOM事件冒泡与捕获**:事件流的两种模式,理解它们对于处理复杂事件交互至关重要。冒泡是从最深的节点开始向上逐级传播事件,而捕获则从文档根节点向下到目标节点。 9. **DOMContentLoaded和load事件**:...

    (JavaScript)Dom入门35个简单实例

    在这个"(JavaScript)Dom入门35个简单实例"的压缩包中,你将找到一系列帮助初学者理解DOM操作的实践教程。 1. **添加和删除元素**:在这些实例中,你将学习如何使用`createElement()`和`appendChild()`方法动态创建...

    Dom.rar_DOM

    7. **DOM事件流**:包括捕获阶段、目标阶段和冒泡阶段,理解这一机制对于优化事件处理至关重要。 8. **DOM2级和DOM3级**:DOM的后续版本增加了更多的功能,如样式操作、XML支持、事件接口等。 9. **性能优化**:...

    分别使用DOM和DOM4j解析XML文件

    不论选择哪种方法,理解XML解析的基本原理和不同库的优缺点对于提高代码质量和效率至关重要。 总结来说,DOM和DOM4j都是解析XML的有效工具,各有其适用场景。DOM4j因其简便的API和出色的性能,成为了Java开发中的...

Global site tag (gtag.js) - Google Analytics