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有问题欢迎与我讨论,共同进步。

  • 相关阅读:
    linux性能测试(转)
    mysql基本操作(数据库,表,字段,记录)
    mysql数据库的简介(安装和卸载)
    mysql数据库
    枚举法
    python数据结构与算法简介
    自学心得
    python 进程线程阅读摘抄
    python并发编程多线程基础1
    python队列
  • 原文地址:https://www.cnblogs.com/starof/p/6555142.html
Copyright © 2011-2022 走看看