zoukankan      html  css  js  c++  java
  • 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;
       
      }

  • 相关阅读:
    Kubernetes节点维护
    Kubernetes helm配置国内镜像源
    windows universal app中使用mvvm light
    windows phone 开发常用小技巧
    异步编程中的最佳做法(Async/Await) --转
    windows phone 开发常用小技巧
    windows phone 开发常用小技巧
    windows phone 开发常用小技巧
    #假期归来# 看看国外开发者第一时间用swift写的Flappy Bird (2014.6.3)
    vs2013 TFS如何彻底删除团队项目
  • 原文地址:https://www.cnblogs.com/rooney/p/1358194.html
Copyright © 2011-2022 走看看