`
djob2008
  • 浏览: 130409 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

(转载)JavaScript的事件深入理解

阅读更多
在很多语言的学习中,“事件”都是一个比较难理解,但是又是一个很重要的概念。JavaScript中的事件处理也是一样,正因为有了事件处理,才会出现Ajax拖动的效果。本文就讨论一下JavaScript中的事件处理,读过之后,您就会知道,很多Ajax框架实现拖动效果的原理了。
一、 IE Event对象
(一)IE Event对象的主要属性和方法
  在IE中有一个专门负责事件处理的对象Event,这个对象负责对事件的处理,含有很多的属性和方法,通过这些方法和属性的调用,就能完成很多的事件处理。
  type:事件的类型,就是HTML标签属性中,没有“on”前缀之后的字符串,例如“Click”就代表单击事件。
  srcElement:事件源,就是发生事件的元素。
  button:声明了被按下的鼠标键,是一个整数。1代表鼠标左键,2代表鼠标右键,4代表鼠标的中间键,如果按下了多个鼠标键,就把这些值加在一起,所以3就代表左右键同时按下。
  clientX/clientY:是指事件发生的时候,鼠标的横、纵坐标,返回的是整数,它们的值是相对于包容窗口的左上角生成的。
  offsetX/offsetY:鼠标指针相对于源元素的位置,可以确定单击Image对象的哪个象素。
  altKey,ctrlKey,shiftKey:顾名思义,这些属性是指鼠标事件发生的时候,是否同时按住了Alt、Ctrl或者Shift键,返回的是一个布尔值。
  keyCode:返回keydown和keyup事件发生的时候,按键的代码以及keypress事件的Unicode字符。
  fromElement、toElement前者是指代mouseover事件移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素。
  cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素。
  returnValue:一个布尔值属性,设置为false的时候可以组织浏览器执行默认的事件动作,相当于<a href=”#” onclick=”ProcessMethod();return false;” />。
  attachEvent()和detachEvent()方法:为制定DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在attachEvent()事件执行的时候,this关键字指向的是window对象,而不是发生事件的那个元素。
  (二)IE Event对象的一些说明
  1.IE Event对象是一个全局属性
  在IE中,不能把Event对象作为参数传递给事件处理程序,只能用window.event或者event来引用Event对象。因为在IE中,Event是window的一个属性,也就是说event是一个全局变量,这个变量提供了事件的细节。
  2.IE中事件的起泡:IE中事件可以沿着包容层次一点点起泡到上层,也就是说,下层的DOM节点定义的事件处理函数,到了上层的节点如果还有和下层相同事件类型的事件处理函数,那么上层的事件处理函数也会执行。例如,<div>标签包含了<a>,如果这两个标签都有onclick事件的处理函数,那么执行的情况就是先执行<a>标签的onclick事件处理函数,再执行<div>的事件处理函数。如果希望<a>的事件处理函数执行完毕之后,不希望执行上层的<div>的onclick的事件处理函数了,那么就把cancelBubble设置为false即可。
  
二、 IE中拖动DOM元素的例子
/*
该函数由mousedown事件处理调用
它为随后发生的mousemove和mouseup事件注册了临时的捕捉事件处理程序
并用这些事件处理程序拖动指定的文档元素
第二个参数必须是mousedown事件的事件对象
*/
function beginDrag(elementToDrag,event)
{
//该元素当前位于何处
//该元素的样式性质必须具有left和top css属性
//此外,我们假定他们用象素做单位
//var x=parseInt(elementToDrag.style.left);
//var y=parseInt(elementToDrag.style.top);

//计算一个点和鼠标点击之间的距离,下面的嵌套的moveHandler函数需要这些值
var deltaX=event.clientX-parseInt(elementToDrag.style.left);
var deltaY=event.clientY-parseInt(elementToDrag.style.top);

// 注册mousedown事件后发生的mousemove和mouseup事件的处理程序
// 注意,它们被注册为文档的捕捉事件处理程序
// 在鼠标按钮保持按下的状态的时候,这些事件处理程序保持活动的状态
// 在按钮被释放的时候,它们被删除
document.attachEvent("onmousemove",moveHandler);
document.attachEvent("onmouseup",upHandler);

//我们已经处理了该事件,不要让别的元素看到它
event.cancelBubble=true;
event.returnValue=false;

/*
这是在元素被拖动时候捕捉mousemove事件的处理程序,它响应移动的元素

*/
function moveHandler(e)
{
//把元素移动到当前的鼠标位置
e=window.event;
elementToDrag.style.left=(event.clientX-deltaX)+"px";
elementToDrag.style.top=(event.clientY-deltaY)+"px";

//不要让别的元素看到该事件
event.cancelBubble=true;

}

/*
该事件将捕捉拖动结束的时候发生的mouseup事件
*/
function upHandler(e)
{
//注销事件处理程序
document.detachEvent("onmouseup",upHandler);
document.detachEvent("onmousemove",moveHandler);}

event.cancelBubble=true;
}
调用它的HTML文件代码:
 <html>
 <head>
  <title>Untitled Page</title>
  <script type="text/javascript" src="dragIE.js"></script>
 </head>
 <body>
 <div style="position:absolute;left:100px;top:100px;background-color:White;border:solid black;">
  <div style="background-color:Gray;border-bottom:solid black;padding:3px;font-family:Sans-Serif;font-weight:bold;" onmousedown="beginDrag(this.parentNode,event);">
  拖动我
  </div>
  <div>
  <p>This is a test.Testing,testing</p></div>
 </div>
 </body>
三、 DOM中的高级事件处理
IE 6中的事件处理,并不是W3C DOM标准的事件处理模型,所以如果上述代码运行在Mozilla Firefox的浏览器中,就会失去作用,同时即将发布的IE 7也将支持W3C DOM的二级标准,所以掌握DOM的高级事件处理显得就很重要了,因为W3C DOM二级标准是未来Web的发展方向,同时W3C DOM的API非常常用,为未来更加复杂的Web开发提供了良好的基础。
(一)事件处理程序的作用域和事件的传播
  在正式讨论DOM高级事件处理之前,我们有必要了解一下事件处理程序的作用域。事件处理程序的作用域要比普通的函数作用域复杂很多。普通的函数作用域链比较容易,例如在一个普通函数中查找一个变量a,那么JavaScript解释器会先在该函数的调用对象中查找是否有a这个变量,如果没有,将会在作用域链的下一个对象,一般是全局对象中查找。但是事件处理程序没这么简单,特别是用HTML的属性定义的,它们的作用域链的头部是调用它们的对象,而下一个对象并不是全局对象,而是触发事件处理程序的对象。这样就会出现一个问题,window和document都有一个方法open(),如果open()前面不加修饰,那么在事件处理的函数中将会调用document.open()方法,而不是常用的window.open()方法,所以使用的时候应该明确指明是window.open()。
(二)事件传播和注册事件处理程序
1.事件传播
  在二级DOM标准中,事件处理程序比较复杂,当事件发生的时候,目标节点的事件处理程序就会被触发执行,但是目标节点的父节点也有机会来处理这个事件。事件的传播分为三个阶段,首先是捕捉阶段,事件从Document对象沿着DOM树向下传播到目标节点,如果目标的任何一个父节点注册了捕捉事件的处理程序,那么事件在传播的过程中就会首先运行这个程序。下一个阶段就是发生在目标节点自身了,注册在目标节点上的相应的事件处理程序就会执行;最后是起泡阶段,事件将从目标节点向上传回给父节点,同样,如果父节点有相应的事件处理程序也会处理。在IE中,没有捕捉的阶段,但是有起泡的阶段。可以用stopPropagating()方法来停止事件传播,也就是让其他元素对这个事件不可见,在IE 6中,就是把cancelBubble设置为true。
2.注册事件处理程序
  和IE一样,DOM标准也有自己的事件处理程序,不过DOM二级标准的事件处理程序比IE的强大一些,事件处理程序的注册用addEventListner方法,该方法有三个参数,第一个是事件类型,第二个是处理的函数,第三个是一个布尔值,true表示制定的事件处理程序将在事件传播的阶段用于捕捉事件,否则就不捕捉,当事件发生在对象上才触发执行这个事件处理的函数,或者发生在该对象的字节点上,并且向上起泡到这个对象上的时候,触发执行这个事件处理的函数。例如:document.addEventListener("mousemove",moveHandler,true);就是在mousemove事件发生的时候,调用moveHandler函数,并且可以捕捉事件。
  可以用addEventListener为一个事件注册多个事件处理的程序,但是这些函数的执行顺序是不确定,并不像C#那样按照注册的顺序执行。
  在Mozilla Firefox中用addEventListener注册一个事件处理程序的时候,this关键字就表示调用事件处理程序的文档元素,但是其他浏览器并不一定是这样,因为这不是DOM标准,正确的做法是用currentTarget属性来引用调用事件处理程序的文档元素。
3.二级DOM标准中的Event
  和IE不同的是,W3C DOM中的Event对象并不是window全局对象下面的属性,换句话说,event不是全局变量。通常在DOM二级标准中,event作为发生事件的文档对象的属性。Event含有两个子接口,分别是UIEvent和MutationEvent,这两个子接口实现了Event的所有方法和属性,而MouseEvent接口又是UIEvent的子接口,所以实现了UIEvent和Event的所有方法和属性。下面,我们就看看Event、UIEvent和MouseEvent的主要属性和方法。
  1.Event
   type:事件类型,和IE类似,但是没有“on”前缀,例如单击事件只是“click”。
   target:发生事件的节点。
   currentTarget:发生当前正在处理的事件的节点,可能是Target属性所指向的节点,也可能由于捕捉或者起泡,指向Target所指节点的父节点。
   eventPhase:指定了事件传播的阶段。是一个数字。
   timeStamp:事件发生的时间。
   bubbles:指明该事件是否起泡。
   cancelable:指明该事件是否可以用preventDefault()方法来取消默认的动作。
   preventDefault()方法:取消事件的默认动作;
   stopPropagation()方法:停止事件传播。
  2.UIEvent
   view:发生事件的window对象。
   detail:提供事件的额外信息,对于单击事件、mousedown和mouseup事件都代表的是点击次数。
  3.MouseEvent
   button:一个数字,指明在mousedown、mouseup和单击事件中,鼠标键的状态,和IE中的button属性类似,但是数字代表的意义不一样,0代表左键,1代表中间键,2代表右键。
   altKey、ctrlKey、shiftKey、metaKey:和IE相同,但是IE没有最后一个。
   clientX、clientY:和IE的含义相同,但是在DOM标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientX和clientY都是0,所以在IE中,要想得到事件发生的坐标相对于文档开头的位置,要加上document.body.scrollLeft和document.body.scrollTop。
   screenX、screenY:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要。
   relatedTarget:和IE中的fromElement、toElement类似,除了对于mouseover和mouseout有意义外,其他的事件没什么意义。
(三)兼容于两种主流浏览器的拖动DOM元素的例子
  好了,刚才讲了这么多DOM编程和IE中的事件,那么如何编写兼容IE和Mozilla Firefox两种主流浏览器的拖拽程序呢?代码如下:
function beginDrag(elementToDrag,event)
{
var deltaX=event.clientX-parseInt(elementToDrag.style.left);
var deltaY=event.clientY-parseInt(elementToDrag.style.top);

if(document.addEventListener)
{
document.addEventListener("mousemove",moveHandler,true);
document.addEventListener("mouseup",upHandler,true);
}
else if(document.attachEvent)
{
document.attachEvent("onmousemove",moveHandler);
document.attachEvent("onmouseup",upHandler);

}

if(event.stopPropagation) event.stopPropagation();
else event.cancelBubble=true;
if(event.preventDefault) event.preventDefault();
else event.returnValue=false;

function moveHandler(e)
{
  if (!e) e=window.event; //如果是IE的事件对象,那么就用window.event
  //全局属性,否则就用DOM二级标准的Event对象。
elementToDrag.style.left=(event.clientX-deltaX)+"px";
elementToDrag.style.top=(event.clientY-deltaY)+"px";

if(event.stopPropagation) event.stopPropagation();
else event.cancelBubble=true;

}

function upHandler(e)
{
if(document.removeEventListener)
{
document.removeEventListener("mouseup",upHandler,true);
document.removeEventListener("mousemove",moveHandler,true);}
else
{
document.detachEvent("onmouseup",upHandler);
document.detachEvent("onmousemove",moveHandler);}
}
if(event.stopPropagation) event.stopPropagation();
else event.cancelBubble=true;

}
分享到:
评论

相关推荐

    Javascript - 全面理解 caller,callee,call,apply (转载)

    这篇文章将深入探讨四个关键概念:caller、callee、call和apply,它们都是JavaScript函数操作的核心部分,对于理解和使用高级JavaScript编程至关重要。 首先,我们来了解`caller`和`callee`。在JavaScript的函数...

    javascript资料大全

    属性]集锦.doc"可能整理了JavaScript中的内置对象和它们的属性,这对于深入理解JavaScript的对象模型和内置机制非常有帮助。 "asp.net常用的javascript经典例子.doc"针对的是ASP.NET开发者,展示了如何在ASP.NET...

    (转载)JavaScript中匿名函数,函数直接量和闭包.docx

    在JavaScript中,匿名函数、函数直接...理解并熟练运用这些概念,将有助于提升你的JavaScript编程能力,使代码更加灵活和强大。在实际开发中,它们可以帮助我们创建更安全、更高效的功能,同时避免全局变量带来的问题。

    深入理解JavaScript系列(11) 执行上下文(Execution Contexts)

    简介 从本章开始,我将陆续(翻译、转载、整理)http://dmitrysoshnikov.com/网站关于ECMAScript标标准理解的好文。 本章我们要讲解的是ECMAScript标准里的执行上下文和相关可执行代码的各种类型。 原始作者:Dmitry...

    js提示框-转载+++ js 乱码+++自动提交+滚动图片加载+箭头导航(转载)

    标题中的“js提示框-转载+++ js 乱码+++自动提交+滚动图片加载+箭头导航(转载)”表明这篇内容涵盖了多个JavaScript相关的知识点。这里我们将分别解析这些关键点,并深入探讨它们。 首先,"js提示框"指的是...

    转载的AJAX反转资料

    学习AJAX,我们需要理解如何使用JavaScript创建XMLHttpRequest对象,发送异步请求到服务器,处理服务器的响应,以及使用DOM动态更新页面内容。此外,随着JSON的普及,现在的AJAX通信更多地使用JSON而非XML,因为JSON...

    华为面试试题,很经典,转载

    总结起来,华为面试试题集是一个宝贵的资源,它帮助求职者准备面对具有挑战性的问题,同时提升他们对Java、JavaScript、Struts和Spring等核心技术的深入理解和应用。通过模拟练习和理解这些问题,候选人可以更好地...

    转载类似iphono的加速度滑动效果的Flex容器

    通过分析和运行这些代码,你可以更深入地理解如何在Flex容器中实现类似iPhone的加速度滑动效果。 总之,这个技术点涉及了CSS3 Flex布局、JavaScript触摸事件处理、速度和加速度计算,以及性能优化等多个方面,对于...

    js实现的3d效果(很炫+转载)

    本篇文章将深入探讨如何利用JavaScript实现3D效果,这在现代网页设计中是一个非常吸引人的特性。 首先,我们要了解JavaScript实现3D效果的核心原理。在WebGL库的帮助下,JavaScript可以与GPU进行通信,创建和渲染...

    各种微博分享按钮代码(转载)

    在互联网社交时代,微博成为了...综上所述,实现微博分享按钮不仅涉及到前端技术的运用,还需要对微博平台的API有深入的理解。通过这个过程,开发者可以增强网站的互动性和用户体验,使内容更容易在社交媒体上扩散。

    jsp页面内容滚动(转载)

    本文将深入讲解如何利用HTML、JavaScript以及可能涉及的CSS来实现这一功能。 首先,HTML是网页的基础结构语言,用于定义网页内容的布局和结构。在JSP页面中,我们通常会用HTML标签来构建页面的基本框架,比如`&lt;div&gt;...

    转载app安全

    本文将基于提供的内容,深入探讨移动APP安全测试的关键点,以及针对这些问题的解决方案。 首先,我们需要理解移动APP所面临的威胁。随着智能手机和移动设备的普及,APP已经成为人们日常生活中不可或缺的一部分。...

    [转载]常用的三种树形菜单

    JavaScript是实现动态树形菜单的关键,它提供了事件监听、DOM操作等功能。jQuery是一个广泛使用的JavaScript库,简化了DOM操作,使得创建交互式树形菜单更加便捷。例如,可以使用jQuery的`slideToggle()`函数来优雅...

    易语言网页应用专题(转载)

    5. **源码分析**:提供的E模块源码是学习的好材料,通过阅读和分析源码,可以深入理解易语言如何实现复杂的网页应用功能,提升编程技能。 6. **测试网页**:测试网页可能是用来演示易语言网页应用功能的实例,通过...

    【转载】浏览器的工作原理:新式网络浏览器幕后揭秘

    首先,我们要理解浏览器的核心组成部分:用户界面(UI)后台、浏览器引擎、渲染引擎、网络模块、JavaScript引擎、数据存储等。 1. **用户界面(UI)后台**:这是用户与浏览器交互的部分,包括地址栏、前进/后退按钮...

    小程序UI库 转载

    在本文中,我们将深入探讨这个UI库的特性、用法以及如何在实际开发中有效地利用它。 首先,让我们理解什么是小程序组件。小程序组件是微信小程序(以及其他类似平台如支付宝小程序)中的基础构建块,它们是预先定义...

    不明飞行物:互联网转载

    【标题】:“不明飞行物:互联网转载” 在互联网的广阔天地中,“不明飞行物”(UFO)常常被用来比喻那些难以...在实际开发过程中,深入理解并熟练运用这些知识点,将有助于我们构建更加高效、健壮的JavaScript应用。

    页面刷新方法汇总(转载)

    本文将围绕“页面刷新方法汇总”这一主题,深入探讨各种常见的页面刷新技术,包括JavaScript、HTML以及HTTP协议等相关知识。 首先,我们要理解页面刷新的基本概念。在Web开发中,刷新页面通常意味着重新加载当前...

    xml 解析,下边是位哥们的全新奉献,这里我转载了,谢谢这位哥们。。

    在本文中,我们将深入探讨XML解析的概念、重要性以及如何在实际项目中应用XML解析。 XML的结构严谨,允许自定义标签,这使得它在不同系统间交换数据时具有很高的灵活性。XML文档由元素构成,每个元素可以包含其他...

    jQuery表单验证 转载

    本文将深入探讨如何利用jQuery实现表单验证,以及"jQuery.FormValidator"这个插件的使用方法。 首先,让我们理解jQuery的基本用法。jQuery的核心是选择器,通过选择器可以轻松地获取DOM元素并进行操作。对于表单...

Global site tag (gtag.js) - Google Analytics