`
ronghao
  • 浏览: 457131 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
E9473dd5-1985-3883-ac98-962354ca10b3
张小庆,在路上
浏览量:8808
社区版块
存档分类
最新评论

了解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);
            }
            return this;
        }  
 


给addListener方法里增加了setCapture参数,用于测试捕获事件流。

<body>
<div  id="dd1-ct" style="width:400px;height:400px;border:1px solid #999;padding:2px">Container
    <div id="dd1-item1" style="width:200px;height:200px;border:1px solid #999;padding:2px">Item1
        <div  id="dd1-item2" style="width:100px;height:100px;border:1px solid #999;padding:2px">Item2</div>
    </div>   
</div>
<div id='rh'></div>
</body>
 


效果:

js:

fn1=function(e){
//    e.stopPropagation();
    $('rh').innerHTML+='Item1 clicked!******';
};

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

fn=function(e){
//    e.stopPropagation();
    $('rh').innerHTML+='Container clicked!&&&&&&&&';
};
    
$('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节点再进行冒泡。

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

 


Internet Explorer略微偏离了这里的事件捕获机制,或者说IE不支持捕获事件流。

b、ie6
支持setCapture()方法。
第一种情况:

$('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
  测试效果与冒泡事件流一致。 不再支持setCapture()方法。
结论:正如mootools所做的,避免捕获事件流。

 

谢谢hax的回复,纠正了我的错误。

  • 描述: 测试的HTML
  • 大小: 10.2 KB
分享到:
评论
4 楼 ronghao 2008-03-03  
谢谢hax的回复,重新编辑了。
3 楼 hax 2008-03-03  
ronghao 写道
你的意思是IE里就没有实现捕获事件流?


是的。setCapture()的含义是完全不同的。
2 楼 ronghao 2008-03-03  
hax 写道
IE的setCapture()跟capture事件流根本不是一回事情,楼主不要混淆了。

IE里只有bubble,不支持w3c标准的事件模型中的其他部分。

setCapture()是用来让一个元素截获一次超出其范围之外(甚至超出浏览器的范围,这显然可以用来干坏事,也许正是因此,ie7做了改变)的事件,但是通常这次事件结束后,setCapture会被自动复位。setCapture的用途主要是用于drag&drop。

你的意思是IE里就没有实现捕获事件流?
1 楼 hax 2008-03-02  
IE的setCapture()跟capture事件流根本不是一回事情,楼主不要混淆了。

IE里只有bubble,不支持w3c标准的事件模型中的其他部分。

setCapture()是用来让一个元素截获一次超出其范围之外(甚至超出浏览器的范围,这显然可以用来干坏事,也许正是因此,ie7做了改变)的事件,但是通常这次事件结束后,setCapture会被自动复位。setCapture的用途主要是用于drag&drop。

相关推荐

    DOM事件的区别

    ### DOM事件的区别详解 在Web开发中,DOM...同时,了解事件流的概念有助于我们更好地控制事件的触发时机。而事件委托技术则提供了一种高效管理大量事件处理器的方法。掌握这些知识对于提升前端开发技能至关重要。

    DOM 事件流详解

    在深入了解DOM(文档对象模型)事件流之前,我们需要先明确事件流的概念。事件流是指当在DOM中发生一个事件时,浏览器是如何处理这个事件的。在处理过程中,事件会从一个元素流向另一个元素,直到整个页面的所有元素...

    深入理解JS DOM事件机制

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

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

    标题中的"JavaScript事件学习小结(一)事件流"指的是JavaScript中的事件...了解事件流有助于优化事件处理,避免不必要的事件处理和提高性能。通过合理利用事件流,开发者可以创建更加高效和用户友好的网页应用程序。

    DOM.zip_JavaScript dom_it

    因此,了解DOM的最小化操作,如批量操作、使用文档碎片、事件委托等技巧是必要的。 10. **DOM2级和DOM3级**:DOM不断发展,DOM2级扩展了事件、样式和遍历等功能,DOM3级则增加了错误处理和XML支持。 总的来说,...

    DOM 事件的深入浅出(一)

    本文就将带大家深入浅出地了解DOM事件的那些属性和方法。 首先在介绍DOM事件之前我们先来认识下DOM的不同级别。针对不同级别的DOM,我们的DOM事件处理方式也是不一样的。 DOM级别与DOM事件 DOM级别一共可以分为4个...

    dom4j所依赖的所有jar包

    首先,我们要了解DOM4J的核心概念。DOM(Document Object Model)是一种W3C标准,用于表示XML文档的结构。DOM4J则是基于DOM的一种轻量级API,它弥补了DOM的一些不足,比如性能问题和内存消耗。DOM4J通过提供SAX...

    DOM.zip_HTML dom_zip

    7. **DOM事件流**:理解捕获和冒泡事件流的概念,以及如何控制事件的传播路径。 8. **性能优化**:学习DOM操作的最佳实践,以减少对页面渲染性能的影响,如批量操作、使用文档碎片等。 9. **DOM API**:熟悉各种...

    dom4j-2.1.3.zip

    在本篇文章中,我们将深入探讨DOM4J 2.1.3版本,了解其核心特性、用途以及如何利用它来处理XML文档。 首先,DOM4J的核心在于其对DOM模型的优化,使得在处理大型XML文件时性能更优,内存占用更低。在"dom4j-2.1.3....

    Javascript Event事件中IE与标准DOM的比较

    JavaScript中的事件处理在不同的浏览器环境下,尤其是Internet Explorer (IE) 和遵循Document Object Model (DOM) 规范的浏览器之间存在显著差异。以下是这些差异的详细解释: 1. **事件流的区别**: - **IE冒泡型...

    dom4j_1.6.1.jar dom4j_2.1.0.jar

    它不仅支持W3C的DOM API,还提供了基于事件的SAX和直接的DOM接口。 2. **核心概念**:主要包括Document(文档对象)、Element(元素)、Attribute(属性)、Text(文本)、Namespace(命名空间)等,这些构成了XML...

    Vue.js 事件修饰符的使用教程

    同时,了解DOM事件流的基本概念,包括事件捕获、处于目标和事件冒泡三个阶段,对于编写有效的事件处理逻辑至关重要。 最后,文章强调了Vue.js处理事件的便利性,它通过内置的修饰符帮助开发者从繁琐的DOM事件细节中...

    JavaScrpt DOMscripting编程艺术

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

    dom jdom sax dom4j 原理性能比

    首先,我们来了解DOM(Document Object Model)。DOM是W3C组织定义的一种API,它将XML文档解析为一个树形结构,允许开发人员通过节点操作来访问和修改XML内容。DOM的优点在于其直观易用,可以方便地遍历整个文档并...

    DOM事件探秘篇

    首先,我们要了解事件流。事件流描述了事件在网页元素间传播的顺序。主要有两种事件流模式: 1. 事件冒泡流:这是最常见的事件传播方式,事件从最具体的元素(如按钮或文本输入框)开始,然后逐级向上层元素传递,...

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

    10. **DOM事件流**:理解捕获阶段、目标阶段和冒泡阶段的概念,以及如何利用它们来优化事件处理。 通过这35个实例,你不仅会学习到基础的DOM操作,还会对JavaScript如何与网页交互有深入的理解。实践是最好的老师,...

Global site tag (gtag.js) - Google Analytics