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

了解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事件的那些属性和方法。 首先在介绍DOM事件之前我们先来认识下DOM的不同级别。针对不同级别的DOM,我们的DOM事件处理方式也是不一样的。 DOM级别与DOM事件 DOM级别一共可以分为4个...

    javascript下对于事件、事件流、事件触发的顺序随便说说

    如:用户点击 也就是常用的click事件 事件流:多个事件 按一定顺序触发 形成了事件流 事件名称:如上面所讲的click就是事件名 事件处理函数/事件监听函数(Dom的叫法)就是 事件触发后的处理函数,如obj.onclick=fn;...

    前端面试宝典V3.0.docx

    8、dom 事件流?(必会) 107 9、什么是事件冒泡,它是如何工作的?如何阻止事件冒泡?(必会) 108 10、JavaScript 动画和 CSS3 动画有什么区别?(必会) 108 11、event 对象的常见应用?(必会) 109 12、自定义...

    了解html页面的渲染过程以备学习前端的性能优化

    参考:Understanding the renderer 页面的渲染有以下特点: •单线程事件轮询 •定义明确、连续、操作有序(HTML5) •分词和构建DOM树 •请求资源并预加载 •构建渲染树并绘制页面 具体来说: 当我们从网络上得到...

    在Python中处理XML的教程

    SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。 正常情况下,优先考虑SAX,因为DOM实在太占内存。 在Python中使用SAX解析XML非常简洁,通常我们关心的事件是start_element,end_...

    ActionScript开发人员指南中文版

    使用ActionScript处理DOM事件 响应未捕获的JavaScript异常 使用JavaScript处理运行时事件 第章:在移动应用程序中显示HTML内容 StageWebView对象 内容 导航事件 历史记录 焦点 位图捕获 第章:安全性 FlashPlatform...

    React框架与Docker容器化精髓 探索livegoods房屋海选平台的交互设计与用户体验优化

    通过学习React的基本原理、组件化开发和虚拟DOM的概念,我掌握了构建可重用、可组合和可维护的用户界面的技巧。我学会了如何使用React的核心API和生命周期方法来管理组件状态和数据流,使我能够更高效地开发用户界面...

    React开发实战

    ◆ 理解React的虚拟DOM架构以及如何利用该架构开发应用程序; ◆ 了解各项功能的原理及重要性; ◆ 深入学习React以及React生态系统中重要的第三方库; ◆ 学习如何创建通用/同构应用程序从而改进用户体验和SEO ...

    Professional JavaScript for Web Developers.pdf

    深入研究基本的web开发概念,如文档对象模型(dom)、浏览器对象模型(bom)、事件、表单、json、错误处理和web动画。 了解高级浏览器api,如地理位置、web工作者、服务工作者、获取、原子、流、消息通道、性能时间...

    React开发实战.pdf 分卷压缩 001

    ◆ 理解React的虚拟DOM架构以及如何利用该架构开发应用程序; ◆ 了解各项功能的原理及重要性; ◆ 深入学习React以及React生态系统中重要的第三方库; ◆ 学习如何创建通用/同构应用程序从而改进用户体验和SEO ...

    React开发实战.pdf 分卷压缩 002

    ◆ 理解React的虚拟DOM架构以及如何利用该架构开发应用程序; ◆ 了解各项功能的原理及重要性; ◆ 深入学习React以及React生态系统中重要的第三方库; ◆ 学习如何创建通用/同构应用程序从而改进用户体验和SEO ...

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

     第一:XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解,等待只会让你失去机会;  第二:新知识肯定会有很多新概念,尝试理解和接受,您才可能提高。不要害怕和逃避,毕竟我们...

    -Building-Declarative-Apps-using-Functional-[removed]使用功能性JavaScript构建声明式应用程序,由Packt发布

    使用功能性JavaScript构建声明性应用[视频] 这是发行的的代码存储库。 它包含从头到尾完成视频课程所...学习处理诸如React和DOM事件之类的管理模式 说明和导航 假设知识 要充分利用本课程所涵盖的范围,您需要: 本课

    html-agility-pack:HTML Agility Pack(HAP)是一个免费的开放源代码HTML解析器,用C#编写,可读写DOM,并支持纯XPATH或XSLT。 这是一个.NET代码库,可让您解析“网络外” HTML文件

    它是一个敏捷HTML解析器,可构建读/写DOM并支持纯XPATH或XSLT(无需了解XPATH或XSLT即可使用它,不用担心...)。 这是一个.NET代码库,可让您解析“网络外” HTML文件。 解析器非常容忍格式错误的“真实世界” HTML...

    大名鼎鼎的IBM公司 Ajax 培训资料

    序流,这恰恰是 Ajax 的强大功能的来源。 在一般的 Web 应用程序中,用户填写表单字段并单击 Submit 按钮。然后整个表单发送到服务器,服 务器将它转发给处理表单的脚本(通常是 PHP 或 Java,也可能是 CGI 进程...

    基于Java实现的秒杀+shiro权限+信息采集等系统的实现源码

    秒杀项目练习 :seckill 该项目总体架构: Maven + SSM 日志: slf4j + logback 数据库相关:Mysql + c3p0 权限控制项目练习:springboot-shiro ...配置模块:单例模式,dom4j解析xml,IOC控制反转

    d3.js 可视化数据PDF

    本书需要读者具有一定的Web 开发经验,特别要了解一些DOM 编程。除此之外,只要对 数据可视化感兴趣,均可阅读学习。 定价:59.00元 读者服务热线:(010)51095186转604 印装质量热线:(010)67129223 反盗版热线:...

    jquery插件使用方法大全

    ·attribute(改进了.attr()的性能)、jQuery()核心函数、CSS(.css()性能有两倍提升)、特效和事件、DOM操作等也有显著改进 1.5 美国时间1月31日John Resig在jQuery官方博客发表文章,宣布jQuery 1.5正式版已经...

    jQuery简介_动力节点Java学院整理

    鉴于它如此流行,又如此好用,所以每一个入门JavaScript的前端工程师都应该了解和学习它。 jQuery这么流行,肯定是因为它解决了一些很重要的问题。实际上,jQuery能帮我们干这些事情: 消除浏览器差异:你不需要...

Global site tag (gtag.js) - Google Analytics