• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
pengpenglin
乐于工作,享受生活。
博客园    首页    新随笔    联系   管理    订阅  订阅
javascript事件学习

1. 事件流

1.IE的事件流是事件冒泡流。 Netscape 的事件流是事件捕获流。

2.IE的事件冒泡:即事件开始是由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。 如 由 div body html document 从左到右进行。

3.事件捕获:意思是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。 如:document html body div 顺序进行。

2.事件处理程序

响应某个事件的函数就叫事件处理程序或事件侦听器。事件处理程序的名字以“on”开头。

1/  html事件处理程序

形式如下:

<input type="button" value="Click me" onclick="alert('clicked')" />
<input type="button" value="click" onclick="showMessage()" />
 2/  DOM0级事件处理程序

就是将一个函数赋值给一个事件处理程序属性。这些属性通常都小写。

var btn=document.getElementById("DOMTest");
      btn.onclick=function(){
          alert(this.id);
      }
      btn.onclick=null;    //在加载时就已经执行了这条,所以上面的onclick事件就执行不了了
3/  DOM2级事件处理程序

DOM2级事件 定义了两个方法。用于处理指定和删除事件处理程序的操作:addEventListener() 和removeEventListener()。

 var btn=document.getElementById("DOMTest");

      btn.addEventListener("click",function(){
          alert(this.id);
      },false);
      btn.addEventListener("click", function(){
          alert(this.nodeName);
      },false);
      //顺序输出: DOMTest BUTTON

      //而要删除这两个事件处理程序时,直接添加下面的代码是没有用的
      //虽然看似使用了相同的参数,但实际上第二个参数与传入addEventListener()
      //中的那个是完全不同的函数
      btn.removeEventListener("click",function(){
          alert("removeEventListener 取消事件")
      },false)

 

使用removeEventListener()的正确方法应是:

 var btn=document.getElementById("DOMTest");

      var hander=function(){
          alert(this.id);
      }
      btn.addEventListener("click",hander,false);
      btn.removeEventListener("click",hander,false); //上面的直接不执行了
4/  IE事件处理程序

IE中实现DOM中类似的两个方法:attachEvent()和detachEvent() 

 var btn=document.getElementById("DOMTest");

 var id="window";
  btn.attachEvent("onclick",function(){
      alert(this.id);      //输出全局中的变量window
  })

 

 

attachEvent的第一个参数是”onclick“

在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。在使用DOM0级方法时,事件处理程序会在其所属元素的作用域内运行。在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。

在ie8及以下这些处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。

 var btn=document.getElementById("DOMTest");

     //var id="window";
      btn.attachEvent("onclick",function(){
          alert("world");      //输出全局中的变量window
      })
      btn.attachEvent("onclick",function(){
          alert("hello");
      })
      //在ie8下顺序显示hello world。
      //在ie9及以上顺序显示world hello

 

使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数,与DOM方法一样,这意味着添加的匿名函数将不能被移除。

5/  跨浏览器的事件处理程序
     var btn=document.getElementById("DOMTest");
      
     var EventUtil={
              addHandler:function(element,type,handler){
                  if ((element.addEventListener)) {
                      element.addEventListener(type,handler,false);
                  }else if (element.attachEvent) {
                      element.attachEvent("on"+type,handler)
                  }else{
                      element["on"+type].handler;
                  }
              },
              removeHandler:function(element,type,handler){
                  if (element.removeEventListener) {
                      element.removeEventListener(type,handler,false);
                  }else if (element.detachEvent) {
                      element.detachEvent(type,handler);
                  }else{
                      element["on"+type].handler;
                  }
              }
          };
          //调用
          var handler=function(){alert(this.nodeName)}
          EventUtil.addHandler(btn,"click",handler);
          //EventUtil.removeHandler(btn,"click",handler);

 

输出结果是: chrome及IE9+中输出 BUTTON, IE8输出indefind;

3.事件对象

1./  DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入到事件处理程序中。

event包含的属性和方法:

  type:被触发事件的类型

  currentTarget:其事件处理程序当前正在处理事件的那个元素。

  target:事件的目标。

  preventDefault():取消事件的默认行为。

  stopPropagation()取消事件的进一步捕获或冒泡。

在事件处理程序内部,对象this始终等于currentTarget的值。而target则只包含事件的实际目标。

如果像DOM0级那样直接将事件处理程序指定给了目标元素,则this,currentTarget,target三个的值一样。

但如果将事件处理程序存在于按钮的父节点中,则这些值则不相同。

var btn=document.getElementById("DOMTest");

      document.body.onclick=function(event){
          alert(event.currentTarget===document.body);
          alert(this===document.body);
          alert(event.target===btn);
      }
      //弹出结果分别是true true true

 

在上面this和currentTarget都等于document.body ,因为事件处理程序是注册在这个元素上,而target元素却等于按钮元素。因为它是click事件真正的目标。click事件冒泡到了document.body,在那里事件才得到了处理。

2/  IE中的事件对象

与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方法,取决于指定事件处理程序的方法。在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。

      var btn=document.getElementById("DOMTest");

    btn.onclick=function(event){
          //var event=window.event;
          alert(event.type);   
      }
      //弹出click,如果去掉var event=window.event;则ie8会报错:无法获取未定义或 null 引用的属性“type”

 

even包含的属性和方法:

  cancelBubble:与stopPropagation()方法作用相同。取消冒泡事件。默认为falue

  returnValue:与preventDefault()方法作用相同。默认为true

  srcElement:与target相同。事件的目标。

  type:被触发事件的类型。

因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为ithis会始终等于事件目标,故而,还是使用event.srcElement比较好。如下:

     var btn=document.getElementById("DOMTest");

    btn.onclick=function(event){
          alert(window.event.srcElement===this);   
      }
      btn.attachEvent("onclick",function(event){
          alert(event.srcElement===this);
      })
    //结果返回: true false

 

3/  跨浏览器的事件对象

var btn=document.getElementById("DOMTest");

     var EventUtil={
              addHandler:function(element,type,handler){
                  if ((element.addEventListener)) {
                      element.addEventListener(type,handler,false);
                  }else if (element.attachEvent) {
                      element.attachEvent("on"+type,handler)
                  }else{
                      element["on"+type].handler;
                  }
              },

              getEvent:function(event){
                  return event ? event : window.event;
              },

              getTarget:function(event){
                  return event.target || event.srcElement;
              },

              preventDefault:function(event){
                  if (event.preventDefault) {
                      event.preventDefault();
                  }else{
                      event.returnValue=false;
                  }
              },

              removeHandler:function(element,type,handler){
                  if (element.removeEventListener) {
                      element.removeEventListener(type,handler,false);
                  }else if (element.detachEvent) {
                      element.detachEvent(type,handler);
                  }else{
                      element["on"+type].handler;
                  }
              },

              stopPropagation:function(event){
                  if(event.stopPropagation){
                      event.stopPropagation();
                  }else{
                      event.cancelBubble=true;
                  }
              }
          };
          //调用
         EventUtil.addHandler(btn,"click", function(event){
             event=EventUtil.getEvent(event);
             alert("clci");

         })

 

posted on 2016-05-15 18:16  pengpenglin  阅读(183)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3