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

作者: JimmyChung | 来源:发表于2016-03-03 17:12 被阅读541次

    本文主要谈及问题:

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

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

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

    近几年来,个人对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 之事件处理函数和事件对象

        本文链接:https://www.haomeiwen.com/subject/exxokttx.html