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中的事件处理机制很有帮助,浅显易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy阅读 3,060评论 1 10
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 1,273评论 3 11
  • 什么是事件: 事件是交互体验的核心功能 一.事件冒泡: 当一个事件发生时,这个事件会从内向外逐层传递。 二.为什么...
    轻描淡写mua阅读 525评论 0 0
  • title: 实现通用的事件注册方法date: 2017-07-15tags: [原生js]categories:...
    始悔不悟阅读 1,074评论 0 0
  • 事件流: 事件流:页面接收事件的顺序。 IE定义的:事件冒泡流(由最具体的元素依次传播到DOM树的最上层的Docu...
    xiaoguo16阅读 603评论 0 0