zoukankan      html  css  js  c++  java
  • 跨浏览器事件对象封装

    封装一个能够隔离浏览器差异的JavaScript库EventUtil,主要是使用能力检测。

    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(){
            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('on'+type,handler);
            }else{
                element['on'+type]=null;
            }
        },
        stopPropagation:function(event){
            if(event.stopPropagation){
                event.stopPropagation();
            }else{
                event.cancelBubble=true;
            }
        }
    };
    View Code

    一、跨浏览器的事件处理程序

    要保证处理事件的代码在大多数浏览器下一致运行,只需要关注冒泡阶段。

    1、添加事件:addHandler

    //添加事件
        /*
        element:要操作的元素
        type:事件名称
        handler:事件处理程序函数
        */
        addHandler:function(element,type,handler){
            if(element.addEventListener){ //存在DOM2级方法,则使用并传入事件类型、事件处理程序函数和第3个参数false(表示冒泡阶段)
                element.addEventListener(type,handler,false);
            }else if(element.attachEvent){//为兼容IE8及更早浏览器,注意事件类型必须加上"on"前缀
                element.attachEvent('on'+type,handler);
            }else{
                element['on'+type]=handler;//其他方法都无效,默认采用DOM0级方法,使用方括号语法将属性名指定为事件处理程序
            }
        }

    2、删除事件

    //移除addHandler添加的事件处理程序
    /*
    element:要操作的元素
    type:事件名称
    handler:事件处理程序函数
    */
    removeHandler:function(element,type,handler){
        if(element.removeEventListener){
            element.removeEventListener(type,handler,false);
        }else if(element.detachEvent){
            element.detachEvent('on'+type,handler);
        }else{
            element['on'+type]=null;
        }
    }
    View Code

     二、跨浏览器事件处理

    1、获取事件

    返回event对象的引用

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

    调用的时候

    btn.onclick=function(event){
        event=EventUtil.getEvent(event);//这行代码添加到开头,确保随时可以使用event对象,不必担心用户使用的什么浏览器
    };

    2、获取目标元素

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

    调用

    btn.onclick=function(event){
        event=EventUtil.getEvent(event);
        var target=Event.getTarget(event);
    };

    3、取消事件默认行为

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

    调用

    var link=document.getElementById("myLink");
    link.onclick=function(event){
        event=EventUtil.getEvent();
        EventUtil.preventDefault(event);
    }

    4、阻止事件冒泡

    stopPropagation:function(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble=true;
        }
    }

    调用

    var link=document.getElementById("myLink");
    link.onclick=function(event){
        event=EventUtil.getEvent();
        EventUtil.stopPropagation(event);
    }
    
    document.body.onclick=function(event){
        alert("Body clicked");
    }

    三、获得相关元素

    getRelatedTarget:function(event){
        if(event.relatedTarget){
            return event.relatedTarget;
        }else if(event.toElement){
            return event.toElement;
        }else if(event.fromEvent){
            return event.fromEvent;
        }else{
            return null;
        }
    }

    四、 获得鼠标按钮

    对于mousedown和mouseup事件,在event对象中存在一个button属性,表示按下或释放的按钮。

    DOM的button属性有3个取值:

    • 0:表示主鼠标按钮(鼠标左键)
    • 1:表示中间的鼠标按钮(鼠标滚轮按钮)
    • 2:表示次鼠标按钮(鼠标右键)

     IE8及之前版本也提供了button属性,但这个属性的值与DOM的button属性有很大差异。

    • 0:表示没有按按钮。——》0
    • 1:表示按下了鼠标左键——》0
    • 2:表示按下了鼠标右键——》2
    • 3:表示同时按下了鼠标左右键——》0
    • 4:表示按下了中间的鼠标按钮——》1
    • 5:表示同时按下了鼠标左键和中间的鼠标按钮——》0
    • 6:表示同时按下了鼠标右键和中间的鼠标按钮——》2
    • 7:表示同时按下了三个鼠标按钮——》》DOM0

    兼容性处理:将IE中其他选项分别转换成如同按下这三个按键中的一个即可(同时将主按钮作为优先选取的对象)。IE中返回的5和7会被转换成DOM模型中的0。由于两种模型有同名的button属性,所以不能直接用能力检测。支持DOM版鼠标事件的浏览器可以通过hasFeature()方法来检测,所以跨浏览器的getButton()方法如下:

    getButton:function(event){
        if(document.implementation.hasFeature("MouseEvents","2.0")){
            return event.button;
        }else{
            switch(event.buton){
                case 0:
                case 1:
                case 3:
                case 5:
                case 7:
                        return 0;
                case 2:
                case 6:
                        return 2;
                case 4:
                        return 1;                                                
            }
        }        
    
    }

    调用:

    var div=document.getElementById("myDiv");
    EventUtil.addHandler(div,"mouseout",function(event){
        event=EventUtil.getEvent(event);
        alert(EventUtil.getButton(event));
    });

    五、获取鼠标滚动增量值

    DOM中当用户向前滚动鼠标滚轮时,wheelDelta是120的倍数;当用户向后滚动鼠标滚轮时,wheelDelta是-120的倍数。

    Opera 9.5之前的版本,wheelDelta值的正负号是颠倒的。

    Firefox支持一个DOMMouseScroll的类似事件,且鼠标有关信息保存在detail属性中。当向前滚动鼠标滚轮时,这个属性的值是-3的倍数,向后滚动鼠标滚轮时,这个值是3的倍数。

    getWheelDelta:function(event){
        if(event.wheelDelta){
            return(client.engine.opera && client.engine.opera<9.5? -event.wheelDelta:event.wheelDelta);
        }else{
            return -event.detail*40; 
        }
    }

    调用:

    可以将相同的事件处理程序指定给mousewheel和DOMMouseScroll事件了。

    (function(){
        function handleMouseWheel(event){
            event=EventUtil.getEvent(event);
            var delta=EventUtil.getWheelDelta(event);
            alert(delta);
        }
        EventUtil.addHandler(document,"mousewheel",handleMouseWheel);
        EventUtil.addHandler(document,"DOMMouseScroll",handleMouseWheel);
    })();

    如果没有封装的话,client.engine.opera 这句代码运行下会报错client is not defined,因为目前还没有封装这个方法,所以等下一个博客我会研究代理检测封装下这个方法; 所以先不考虑opera9.5,先注释掉这句代码;

    六、获取字符编码

    IE9,Firefox,Chrome和Safari的event对象的charCode 属性代表按下那个键所代表字符的ASCII编码。

    IE8及之前版本中Opera是在keyCode中保存字符的ASCII编码。

    检查charCode属性是否可用,不可用则使用keyCode。

    getCharCode:function(event){
        if(typeof event.charCode=="number"){//在不支持的浏览器中值是undefined
            return event.charCode;
        }else{
            return event.keyCode;
        }
    }

    调用

    EventUtil.addHandler(textbox,"keypress",function(event){
        event=EventUtil.getEvent(event);
        console.log(EventUtil.getCharCode(event));
    });  

    本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/6555142.html有问题欢迎与我讨论,共同进步。

  • 相关阅读:
    BZOJ2821 作诗(Poetize) 【分块】
    BZOJ2724 蒲公英 【分块】
    Codeforces 17E Palisection 【Manacher】
    BZOJ2565 最长双回文串 【Manacher】
    Codeforces 25E Test 【Hash】
    CODEVS3013 单词背诵 【Hash】【MAP】
    HDU2825 Wireless Password 【AC自动机】【状压DP】
    HDU2896 病毒侵袭 【AC自动机】
    HDU3065 病毒侵袭持续中【AC自动机】
    HDU2222 Keywords Search 【AC自动机】
  • 原文地址:https://www.cnblogs.com/starof/p/6555142.html
Copyright © 2011-2022 走看看