javascript 之事件处理函数和事件对象

本文主要谈及问题:

  • 关于编写跨浏览器的事件处理函数和事件对象

关于编写跨浏览器的事件处理函数和事件对象

  • 为什么要编写跨浏览器的事件处理函数和事件对象

近几年来,个人对WINDOWS越来越没爱。至于为什么无爱,我想原因有二:

  • 转投MAC阵营,觉得MAC比起WINDOWS对用户太友好了
  • 成为了一个前端工程师

讲讲第二点。网上一直流传着一个段子:IE都有勇气让你把它设为默认浏览器,为什么你还连表白的勇气都没有。每每看到这个段子,心都有点痛,我想不仅是我,每个前端工程师都会有这样的感觉。微软在IE9之前,完全是think different ,make 更加 different。做出来的东西完全跟标准不一致。FE们为了兼容它没少花心思。就拿事件模型来说,基本上最常用的模型有两种:一种是DOM L2 EVENT MODEL.另外一种不用说,相信大家都知道,就是IE EVENT.所以我们就被逼着编写跨浏览器的事件处理函数和事件对象。是不是觉得IE很作死,可是没办法啊,人家还占那么多份额,我们只能乖乖地兼容它。

  • 怎么编写跨浏览器的事件处理函数和事件对象

    • 事件处理函数

      • DOM 事件处理函数(这里只谈及DOM2)
        DOM2级事件定义了两种方法:

        • addEventListener(type,handler,useCapture); --添加事件处理函数
        • removeEventListener(type,handler,useCapture); -- 删除事件处理函数

        这两个方法都有三个参数:type为事件的类型,handler为事件处理程序的函数,userCapture(可选参数)为事件流类型,冒泡为false,捕获为true,默认为false。

      • IE 事件处理函数
        IE 事件定义了两种方法:

        • 添加事件处理函数 :attachEvent("on"+type,handler);
        • 删除事件处理函数 :detachEvent("on"+type,handler);

        这两个方法都有两个参数:第一个参数"on"+type是事件类型(如果在addEventListener的type为click,则此处应该为onclick),第二个参数handler为事件处理程序的函数。注意:IE8之前的浏览器只支持事件冒泡,不支持事件捕获。

      • 区别:

        • 一个元素添加多个事件处理函数的执行顺序:如果为一个元素添加多个事件处理函数,addEVentListener会按照添加的顺序执行代码。而attachEvent会按照添加顺序的相反顺序,如下:

          var btn = document.getElementById('btn');
          btn.addEventListener("click",function(){
          alert("1");
          });
          btn.addEventListener("click",function(){
          alert("2");
          });
          //以上代码先输出1,在输出2   
          
          var btn = document.getElementById('btn');
          btn.attachEvent("onclick"function(){
              alert("1");
          })
          btn.attachEvent("onclick"function(){
           alert("2");
          })
          //以上代码先输出2,再输出1
          
        • 事件处理程序的函数中的this:addEventListener的handler中的this指的是添加该事件处理函数的元素,而attachEvent的handler中的this指的是window对象。如下:

          var bt = document.getElementById("bt");
          bt.addEventListener("click",function(){
            console.log(this === bt)
          })    
          //为true,this指添加事件处理函数的元素
          var bt = document.getElementById("bt");
          bt.attachEvent("onclick",function(){
            console.log(this === window)
          })
          //为true,this指window对象
          
      • 跨浏览器事件处理函数 :
        综合上述的事件处理函数,我们可以写出跨浏览器的事件处理函数,我们可以把它包含在一个对象里。如下:

        var eventForAllBrowsers = {
              addHandler :function(elem,type,handler){
                  if(elem.addEventListener){
                      elem.addEventListener(type,handler,false);
                  } else if(elem.attachEvent){
                      elem.attachEvent("on"+type,handler);
                  } else{
                      elem["on"+type] = handler;
                      //加上对DOM 0 的支持
                  }
              },
              removeHandler:function(elem,type,handler){
                  if(elem.removeEventListener){
                      elem.removeEventListener(type,handler,false)
                  } else if(elem.detachEvent){
                      elem.detachEvent("on"+type,handler);
                  } else {
                      elem["on"+type] = null;
                  }
              }
        }
        
    • 事件对象
    在触发dom上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息,该对象在事件触发完毕后会被自动销毁。
    • DOM 事件对象
      兼容DOM的浏览器会将一个event对象传入到事件处理程序中。在函数内可以访问event对象的属性与方法。如下:
      var bt = document.getElementById('bt');
      bt.addEventListener("click",function(event){
      alert(event.type)
      })
      event对象中包含的常用的属性和方法:
      • preventDefault() --- 取消事件的默认行为。
      • stopPropagation() --- 取消事件的进一步冒泡。
      • type --- 被触发的事件的类型。
      • target --- 事件的目标。
    • IE 事件对象
      与兼容DOM的浏览器不同,要访问IE的event对象分两种情况:
      • 使用DOM 0 方法添加事件处理程序:在程序的函数内,用window.event去访问event对象。如下:

        var bt = document.getElementById('bt');
        bt.onclick = function(){
          var event = window.event;
          alert(event.type)
        }
        
      • 使用IE 事件处理函数:将event对象传入事件处理程序的函数内。如下:

        var bt = document.getElementById('bt');
        bt.attachEvent("onclick",function(event){
          alert(event.type)
        })
        

event对象中包含的常用的属性和方法:
- cacelBubble --- 默认值为false,将其设置为true就可以取消事件冒泡。
- returnValue --- 默认值为true,将其设置为false则可以取消事件的默认行为。
- srcElement --- 事件的目标。
- type --- 被触发事件的类型。

- 跨浏览器的事件对象
  通过检查兼容DOM的浏览器的event对象的方法和属性是否存在的方法去处理跨浏览器兼容性问题。把通用的事件对象的相关函数添加到eventForAllBrowsers上,代码大致如下:
      var eventForAllBrowsers = {
      //省略上述的代码
         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;
                }
            },
            stopPropagation:function(event){
                if(event.stopPropagation){
                    event.stopPropagation();
                }else{
                    event.cancelBubble = true;
                }
            }         
      }

你可能感兴趣的:(javascript 之事件处理函数和事件对象)