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

javascript事件处理机制——容易被我们遗忘的细节问题

    博客分类:
  • js
阅读更多
转自:http://www.iteye.com/topic/299320

最近在细读mootools core源代码中,在阅读到包装Event的时候,才发现,以前没对js事件处理处理机制深入的研究.遂,再次翻开尘封已久的java犀牛书,仔细的阅读了一把.

      我们在书写js程序的时候,在很大程度上,都是写客户端交互程序,所以大部分都可以事件有关.但是遗憾的是,这些事件处理程序的细节非常复杂.并且由于浏览器的不同,目前有四种不同的事件处理机制:

原始事件模型:这是最简单的一种事件处理模型,尽管功能有限,但所有的浏览器都支持它.可以把它看作0级DOM

标准事件模型:这是一种更强大更完整的事件模型.2级DOM标准对它进行了标准化.Netscape 6和Mozilla支持它

Internet Explorer事件模型:具有标准事件模型的许多特性。虽然Microsoft参与了2级DOM事件模型的创建。但IE7一下的版本都没实现2级模型的标准,坚持使用自己的专有的事件模型,IE8以上的不太清楚。这意味着,在ie下运行,要想使用高级事件处理特性的js程序必须编写特定的代码。

Netscape事件模型:这种模型现在已被标准模型取代.不过Netscape6为了向后兼容,还是继续实现了它.

接下来我们讨论这几种事件模型各自的特点以及如何实现一个通用健壮的事件处理程序在你的应用程序中

其实,我们在处理js事件问题的时候,我们就会很自然的去认为事件发生在目标元素上,那么它的事件处理代码就只会在你编写的特定处理函数上执行,例如:有这样一段代码:

   1. <div id="parent" style="height: 100px; width: 200px; background-color: yellow" onclick="parent(event)">  
   2.     <div id="child" style="height: 50px; width: 100px; background-color: gray" onclick="child(event)">  
   3.     </div>  
   4. </div>  

		<div id="parent" style="height: 100px; width: 200px; background-color: yellow" onclick="parent(event)">
			<div id="child" style="height: 50px; width: 100px; background-color: gray" onclick="child(event)">
			</div>
		</div>





   1. var parent = function(e) {  
   2.     alert('parent');  
   3. };  
   4. var child = function(e) {  
   5.     alert('child');  
   6. };  

			var parent = function(e) {
				alert('parent');
			};
			var child = function(e) {
				alert('child');
			};


在通常情况下, 我们会认为当点击parent的时候会打印出'parent'来,点击child的时候会打印出'child'来,但其实则不然,当你点击child的时候,会打印出'parent'和'child'.为什么结果和预想的不一样呢,那是因为我们对js的事件处理机制还建立在原始事件模型上.而浏览器却按照标准事件模型来处理的.那或许有人又有疑问,不是说IE不支持标准事件模型吗?为什么在IE下也会打印出'child'和parent.我们刚刚说了IE 用了自己专业的事件模型处理机制.但是却具有大部分标准事件模型的特性.所以会有这样的结果.那么我们来看看标准事件模型是怎样定义的吧!

     在原始事件模型中,浏览器把事件分派给发生事件的文档元素。如果该那个对象具有适合的事件处理程序,就运行这个程序。初次之外,不用执行其他的操作。但是,在标准事件模型中,情况则要复杂很多。当事件发生在目标元素时,目标的事件处理程序会被触发。此外,目标的每个祖先节点也有机会处理那个事件。事件传播分三个阶段完成。一:在捕捉(capturing)阶段,事件从Document对象沿着文档向下传播给目标节点。在这期间,目标对象的任何祖先节点都可以捕捉的事件并处理它。二:目标节点本身,这和原始时间模型相似,最后一个阶段是起泡阶段:在这个阶段,事件将从目标元素向上传播回 Document对象的文档层次。

     现在就不难理解为什么我们点击child的时候parent的点击事件处理函数也会被执行.这就是我们今天讨论的主题,被忽略的细节.虽然很多人都知道 javascript标准事件模型,但是,大部分人在写事件处理程序的时候却忽略了这些问题.所以.有些时候,在某段页面js代码中插入几段事件代码,却产生莫名的错误或者是与想要的结果有大大的出入.如果说你还没有遇到这样的问题,你应该为此而感到庆幸,那是因为你还没遇到过在一个父元素和子元素处理相同的事件.但这不代表你以后不会遇到.所以为了你代码的健壮性和易维护性.应该重构你的代码.下面这段代码是我的一个实现

   1. var Event = function(event) {  
   2.         this.event = event || window.event;  
   3.         this.target = (function() {  
   4.             var target = this.event.target || this.event.srcElement;  
   5.             while (target && target.nodeType == 3) {  
   6.                 target = target.parentNode;  
   7.             }     
   8.             return target;  
   9.         })();  
  10.           
  11.         this.stop = function(){  
  12.             return this.stopPropagation().preventDefault();  
  13.         }  
  14.           
  15.         this.stopPropagation = function(){  
  16.             if (this.event.stopPropagation) this.event.stopPropagation();  
  17.             else this.event.cancelBubble = true;  
  18.             return this;  
  19.         }  
  20.       
  21.         this.preventDefault = function(){  
  22.             if (this.event.preventDefault) this.event.preventDefault();  
  23.             else this.event.returnValue = false;  
  24.             return this;  
  25.         }  
  26. }  

var Event = function(event) {
		this.event = event || window.event;
		this.target = (function() {
			var target = this.event.target || this.event.srcElement;
			while (target && target.nodeType == 3) {
				target = target.parentNode;
			}	
			return target;
		})();
		
		this.stop = function(){
			return this.stopPropagation().preventDefault();
		}
		
		this.stopPropagation = function(){
			if (this.event.stopPropagation) this.event.stopPropagation();
			else this.event.cancelBubble = true;
			return this;
		}
	
		this.preventDefault = function(){
			if (this.event.preventDefault) this.event.preventDefault();
			else this.event.returnValue = false;
			return this;
		}
}



重构后的事件处理代码:

   1. var parent = function(e) {  
   2.     var event = new Event(e);  
   3.     alert('parent');  
   4. };  
   5. var child = function(e) {  
   6.     var event = new Event(e);  
   7.     alert('child');  
   8.     event.stopPropagation();  
   9. };  

			var parent = function(e) {
				var event = new Event(e);
				alert('parent');
			};
			var child = function(e) {
				var event = new Event(e);
				alert('child');
				event.stopPropagation();
			};


经过这样处理以后,便可保证在任何情况任何环境下照常运行
分享到:
评论

相关推荐

    JavaScript程序设计——事件处理实验报告.docx

    1.实现JavaScript事件注册;...2.实现JavaScript事件处理函数; 3.实现JavaScript鼠标和键盘事件; 4.实现JavaScript表单相关事件; 5.实现JavaScript字幕滚动事件; 6.实现JavaScript编辑事件;

    利用JavaScript实现图片标注——SearchMapIdentityTask

    DOM(Document Object Model)是HTML和XML文档的结构化表示,通过JavaScript我们可以对DOM进行操作,比如添加、删除或修改元素。 在实现`SearchMapIdentityTask`时,我们可能需要以下关键知识点: 1. **事件监听**...

    JavaScript凌厉开发——Ext详解与实践 源码 源代码 part3

    JavaScript凌厉开发——Ext详解与实践 源码 源代码 part3 因为源代码比较大,压缩后76M左右 所以分为四个包上传

    JavaScript调用java方法——dwr步骤.docx

    JavaScript调用java方法——dwr步骤.docx

    JavaScript动态网页开发详解——JavaScript特效

    在“JavaScript动态网页开发详解——JavaScript特效”这一主题中,我们将深入探讨JavaScript如何实现各种炫酷的网页效果。 一、JavaScript基础 在讨论特效之前,我们需要了解JavaScript的基础。JavaScript语法与...

    JavaScript框架高级编程——应用Prototype、YUI、Ext JS、Dojo、MooTools

    JavaScript框架高级编程——应用Prototype、YUI、Ext JS、Dojo、MooTools JavaScript框架高级编程——应用Prototype、YUI、Ext JS、Dojo、MooTools

    JavaScript代码生成器——Coffee Script.pdf

    JavaScript代码生成器——Coffee Script CoffeeScript是一种基于Ruby语言的编程语言,旨在通过简洁的编码方式生成JavaScript代码。它结合了Ruby的简洁和JavaScript的灵活性,使开发者可以通过简洁易读的语法撰写...

    网页模板——扣代码工具 javascript事件 捕获者2.0.zip

    JavaScript事件捕获机制是理解JavaScript事件处理模型的关键部分,它允许我们对页面上的元素进行响应,例如点击、鼠标移动或者键盘输入等。下面将详细阐述这两个主题。 首先,网页模板是一种预先设计的网页结构,...

    《javascript》——event对象与事件

    《JavaScript》——Event 对象与事件 Event 对象是 JavaScript 中的一个基本概念,它代表了用户与 Web 页面的交互行为,例如点击、鼠标移动、键盘输入等。Event 对象的属性和方法可以帮助开发者更好地处理用户的...

    JavaScript特效代码集——rar

    2. **鼠标事件类**:JavaScript中的事件处理是用户交互的核心。代码集中包含了鼠标点击(click)、移动(mousemove)、悬停(mouseover/mouseout)等各种事件的处理方法,可以帮助你创建响应式和互动性强的网页元素...

    JavaScript网页开发——体验式学习教程.pdf

    事件监听器、事件处理函数和事件传播机制是这部分的重点。 AJAX(异步JavaScript和XML)技术使得无需刷新页面就能与服务器交换数据并更新部分网页内容。这在现代Web应用中非常常见,提高用户体验。教程将涵盖...

    JavaScript网页开发——体验式学习教程

    张孝祥老师的“JavaScript网页开发——体验式学习教程”深入浅出地涵盖了JavaScript的基础与高级知识,旨在帮助学习者通过实践掌握这一强大的工具。 首先,教程中会涉及HTML(HyperText Markup Language)和CSS...

    javaScript全面分析——中文版

    JavaScript全面分析——中文版是为想要快速理解和掌握JavaScript编程语言的学者精心编写的教程。JavaScript是一种广泛应用于Web开发的脚本语言,它在浏览器端运行,为网页添加交互性,使得用户界面更加生动活泼。本...

    水面漂浮污染物突发事件应急处理系统设计——分布式消息机制在应急处理流程中的应用.pdf

    【水面漂浮污染物突发事件应急处理系统设计——分布式消息机制在应急处理流程中的应用】 本文将深入探讨一个专门针对上海市某水务管理职能单位设计的B/S架构信息系统——水面漂浮污染物突发事件应急处理系统。该...

    教你一天玩转JavaScript(二)——完成对注册页面的数据的简单校验

    JavaScript的事件监听机制可以帮助我们实现这一功能。例如,可以监听`onblur`事件,当用户离开输入框时进行校验: ```javascript document.getElementById('emailInput').addEventListener('blur', function() { ...

    JavaScript实战手册——第七版代码

    《JavaScript实战手册——第七版代码》是一本专为JavaScript开发者准备的实践指南,它涵盖了从基础到高级的各种JavaScript编程技术。这本书的代码示例旨在帮助读者深入理解语言机制,并提升在实际项目中的应用能力。...

    JavaScript例子——计算

    6. **事件处理**:在网页环境中,JavaScript常与用户交互,通过事件监听(addEventListener)实现点击按钮触发计算等功能。例如: ```html &lt;button id="calcBtn"&gt;Calculate document.getElementById('calcBtn')....

    javascript——PDF教程大合集.rar

    javascript——PDF教程大合集 1、100个直接可以拿来用的JavaScript实用功能代码片段 2、JavaScript DOM编程艺术(中文) 3、JavaScript高级程序设计(第3版)中文 高清 完整 4、JavaScript脚本特效编程给力起飞 5、...

    JavaScript动态网页开发详解——源文件

    在"JavaScript动态网页开发详解——源文件"中,我们可以深入学习到JavaScript在网页开发中的应用技巧。此资料可能包含了JQUERY的官方实例全集,jQuery是一个高效、简洁且富有创造性的JavaScript库,它极大地简化了...

    服务器端JavaScript——NodeJS

    【服务器端JavaScript——NodeJS】 Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它让JavaScript能够在服务器端执行,打破了JavaScript长期以来只能在浏览器中运行的限制。Node.js使用了一个事件驱动、非...

Global site tag (gtag.js) - Google Analytics