`
javaplan
  • 浏览: 54948 次
  • 性别: Icon_minigender_1
  • 来自: world
社区版块
存档分类
最新评论

javascript中事件的理解

阅读更多
 
 
在javascript中,event事件是一个必不可少的讨论话题,它在和用户的交互中起到了很重要的作用。今天我们就来讨论一下JavaScript中的事件处理,并且结合它来阐叙Ajax框架实现拖动效果的原理了。
一、 Event对象
    1    Event对象的主要属性和方法
  event代表事件的状态,专门负责对事件的处理,它的属性和方法能帮助我们完成很多和用户交互的操作,下面我们就来看看它的一些属性和方法。
         type:事件的类型,就是HTML标签属性中,没有“on”前缀之后的字符串,例如“Click”就代表单击事件。

  srcElement:事件源,就是发生事件的元素。比如<a onclick="check()"></a> a这个链接是事件发生的源头,也就是该事件的srcElement。

  button:声明了被按下的鼠标键,是一个整数。0代表没有按键,1代表鼠标左键,2代表鼠标右键,4代表鼠标的中间键,如果按下了多个鼠标键,就把这些值加在一起,所以3就代表左右键同时按下。

  clientX/clientY:是指事件发生的时候,鼠标的横、纵坐标,返回的是整数,它们的值是相对于包容窗口的左上角生成的。

  offsetX/offsetY:鼠标指针相对于源元素的位置,可以确定单击Image对象的哪个象素。

  altKey,ctrlKey,shiftKey:顾名思义,这些属性是指鼠标事件发生的时候,是否同时按住了Alt、Ctrl或者Shift键,返回的是一个布尔值。

  keyCode:返回keydown和keyup事件发生的时候,按键的代码以及keypress事件的Unicode字符。比如event.keyCode=13代表按下了回车键;

  fromElement、toElement前者是指代mouseover事件移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素。

  cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素,它用于检测是否接受上层元素的事件的控制。true代表不被上层元素的事件控制,false代表允许被上层元素的事件控制。

  returnValue:一个布尔值属性,设置为false的时候可以阻止浏览器执行默认的事件动作,相当于<a href=”#” onclick=”ProcessMethod();return false;” />。

          attachEvent()和detachEvent()方法:为制定DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在attachEvent()事件执行的时候,this关键字指向的是window对象,而不是发生事件的那个元素。

    2     IE Event对象的一些说明
  Event对象是一个全局属性
  在IE中,不能把Event对象作为参数传递给事件处理程序,只能用window.event或者event来引用Event对象。因为在IE中,Event是window的一个属性,也就是说event是一个全局变量,这个变量提供了事件的细节。
3 关于事件的起泡的概念

         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);">
    拖动我&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </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;
    
最后我们来回顾一下事件执行过程中的三个阶段:
1 捕捉阶段,事件从Document对象沿Dom解析的树向下传播给目标节点。

2 目标节点触发阶段 事件处理程序在目标上的运行阶段
3 起泡阶段 事件从目标元素向上传播或者起泡回Document对象的文档层次。

分享到:
评论

相关推荐

    深入理解JavaScript系列

    本书是一本全面、深入介绍JavaScript语言的学习指南。本书共分四个部分,第1部分帮助读者快速入手,掌握基本的JavaScript编程要点;第2部分介绍JavaScript的发展和技术背景;第3部分深入探索JavaScript,介绍了语法...

    深入理解JavaScript 5分

    深入理解JavaScript深入理解JavaScript深入理解JavaScript

    深入理解JavaScript系列(.chm)

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(3):全面解析Module模式 深入理解JavaScript系列(4):立即调用...

    深入理解Javascript系列

    深入理解Javascript系列

    JavaScript自定义事件的创建与应用:深入指南

    通过本文的介绍,你应该对如何在JavaScript中创建和使用自定义事件有了深入的理解。记住,合理地使用自定义事件可以显著提升你的Web应用程序的交互性和可维护性。 通过本文的介绍,你应该对如何在JavaScript中创建...

    理解javascript中undefined和null的区别

    理解javascript中undefined和null的区别

    javascript常用事件应用

    在这个飞机大战(可能是一个教学示例)程序中,我们可以深入理解JavaScript事件的应用。 1. **事件**:在JavaScript中,事件是用户或浏览器执行的特定动作,比如点击按钮、滚动页面或按下键盘键。事件驱动了...

    javaScript 中文开发文档

    JavaScript是一种广泛应用于Web开发的脚本语言,它主要在客户端运行,为网页添加交互性。...通过阅读和实践其中的内容,开发者可以深入理解JavaScript的核心概念,并学会如何在实际项目中应用这些知识。

    深入理解JavaScript系列(汤姆大叔)

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(3):全面解析Module模式 深入理解JavaScript系列(4):立即调用...

    550836 深入理解JavaScript [(美)罗彻麦尔著]_jvascript_

    此外,本书还会讲解JavaScript的异步编程,包括事件循环、回调函数、Promise以及现代的async/await语法,这些都是编写非阻塞代码、处理异步操作的关键技术。 最后,随着JavaScript的发展,ES6(ECMAScript 2015)...

    探究JavaScript中的五种事件处理程序方式

    本文将详细阐述JavaScript中的五种事件处理程序方式,帮助开发者更好地理解和使用这些机制。 1. HTML事件处理程序 这是最基础的事件处理方式,通过在HTML元素中直接添加以"on"开头的属性来指定事件处理程序。例如,...

    ASP中的JavaScript

    4. **ASP中的JavaScript事件处理** - **服务器端事件**:通过在HTML元素上绑定ASP事件处理程序,如`&lt;input type="button" onClick="&lt;% Response.Write "JavaScript函数名()" %&gt;" /&gt;`。 - **客户端事件**:同时,...

    javascript中文参考手册

    《JavaScript中文参考手册》是一本详尽介绍JavaScript语言的电子书,它为学习和理解JavaScript提供了丰富的资源。这本书涵盖了JavaScript的基本语法、数据类型、控制结构、函数、对象、DOM操作、AJAX异步通信以及...

    javascript语言精粹 pdf

    事件驱动编程也是JavaScript的一大特色,尤其是在Web开发中。通过监听和响应用户或浏览器的事件,我们可以创建交互性强的网页应用。理解事件循环机制和事件委托策略,能有效提高性能并避免回调地狱。 此外,...

    arcgis api for javascript 中文帮助文档和demo

    中文帮助文档是开发者在使用ArcGIS API for JavaScript时的重要参考资料,它详细地解释了各种函数、类、方法和属性,以及如何将它们应用于实际项目中。文档通常会按照功能模块划分,如地图操作、图层管理、服务调用...

    head first JavaScript源码

    通过阅读源码,读者不仅可以学习到理论知识,还能看到这些知识如何在实践中得以体现,这对于初学者深入理解和掌握JavaScript语言非常有帮助。同时,书中丰富的图片和直观的示例使得学习过程更为生动有趣。如果你想要...

    asp.net中TextBox获得焦点和失去焦点——客户端JavaScript事件

    首先,我们要理解JavaScript事件。JavaScript是一种运行在客户端浏览器上的脚本语言,它能监听用户行为和页面状态的变化,然后触发相应的函数。在TextBox中,两个关键的事件是`focus`和`blur`。 1. `focus`事件:当...

    零基础学JavaScript中

    在这个"零基础学JavaScript中"的学习过程中,我们可以分为16个关键课程来逐步深入理解这门语言: 1. **课程1:JavaScript简介** - 介绍JavaScript的历史、用途以及在网页开发中的角色,解释如何在HTML中插入...

Global site tag (gtag.js) - Google Analytics