模拟一个自己的jquery(三) 事件

模拟bind方法与unbind方法

jquery的bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。

模拟的bind事件主要是针对ie与w3c事件模型的不一致提供一个统一的接口。然后再设置绑定事件的上下文为触发事件的元素,也就是在事件中能够通过this访问到触发事件的元素。

unbind:移除掉绑定的方法。

trigger:触发某个事件:如$("#bt1").trigger("click") 则会触发id为bt1的点击事件

event.js代码

    /*!Event 事件处理 模拟jquery的bind与unbind
     *
     *Date   2014-4-10
     *author meng
    */
(function(_window){
    _window.MQuery.fn.bind=function(evt,fun,useCapture){
        //定义handle统一处理回调事件 handle封装事件默认的e参数,针对IE与标准的不同实现提供一个统一接口。
        var handle=function(e){
            var evt=e||_window.event;
            //检查是否是w3c模式
            var isW3c=evt.toString&&evt.toString().indexOf("MouseEvent")!=-1;
            //封装e 兼容w3c模式与ie模式
            var evtArg={};
            for(var p in evt){
                evtArg[p]=evt[p];
            }
            evtArg.target=evt.target||evt.srcElement;
            //阻止事件默认行为
            evtArg.preventDefault=function(){
                if(evt.preventDefault){
                    evt.preventDefault();
                }
                else{
                    evt.returnValue =false;
                }
            }
            //停止事件冒泡
            evtArg.stopPropagation=function(){
                if(evt.stopPropagation){
                    evt.stopPropagation();
                }
                else{
                    evt.cancelBubble=true;
                }
            }
            //判断鼠标点击事件点击了(左、中、右)哪个键
            //w3c与ie都使用button代表点击的哪个键
            //w3c:0左键 1中键 2右键
            //IE:0没有按键 1左键 2中键 3同时按下左右键 4中键 5同时按下左中键 6同时按下右中键 7同时按下左中右键
            var buttons={
                "left":false,
                "middle":false,
                "right":false
            }
            if(isW3c){
                //W3c
                switch(event.button){
                    case 0:buttons.left=true;break;
                    case 1:buttons.middle=true;break;
                    case 2:buttons.right=true;break;
                    default:break;
                }
            }
            else if(event.button){
                //Ie
                switch(event.button){
                    case 1:buttons.left=true;break;
                    case 2:buttons.right=true;break;
                    case 3:buttons.left=true;buttons.right=true;break;
                    case 4:buttons.middle=true;break;
                    case 5:buttons.left=true;buttons.middle=true;break;
                    case 6:buttons.middle=true;buttons.right=true;break;
                    case 7:buttons.left=true;buttons.middle=true;buttons.right=true;break;
                    default:break;
                }
            }
            evtArg.buttons=buttons;

            //判断键盘点击事件,w3c与ie均提供了keycode获取按键的代码 通过string.fromCharCode方法获取具体的键盘字母值
            //同时检查是否按了ctrl、shift、alt。
            //把按键值存入keycodenames属性
            evtArg.keyCodeNames=evt.keyCode?[String.fromCharCode(evt.keyCode)]:[];
            if(evt.altKey){
                evtArg.keyCodeNames.push('ALT');
            }
            if(evt.shiftKey){
                evtArg.keyCodeNames.push('SHIFT');
            }
            if(evt.ctrlKey){
                evtArg.keyCodeNames.push('CTRL');
            }
            //获取默认的参数e
            evtArg.get=function(){
                return evt;
            }
            //获取事件触发元素
            //通过fun的call调用设置触发元素为事件的上下文
            fun.call(evtArg.target,evtArg);
        }
        //把原函数设置为handle的一个属性,这样移除事件的时候通过原函数找到handle,才能移除
        handle.sour=fun;
        handle.funName=evt;
        useCapture=useCapture||false;
        //绑定事件
        this.each(function(x){
            if(!x.events){
                x.events=[];
            }
            x.events.push(handle);
            if(x.addEventListener){
                x.addEventListener(evt,handle,useCapture);
                console.log('w3c');
            }
            else if(x.attachEvent) {
                x.attachEvent('on'+evt,handle);
                console.log('ie');
            }
        })
    }
    _window.$.fn.unbind=function(evt,fun,useCapture){
        useCapture=useCapture||false;
        this.each(function(x){
            //x.events不为undefined才移除事件
            if(x.events){
                for(var i=0;i<x.events.length;i++){
                    var handle=x.events[i];
                    if(handle){
                    if(handle.sour==fun&&handle.funName==evt){
                        if(x.removeEventListener){
                            x.removeEventListener(evt,handle,useCapture);
                        }
                        else if(x.detachEvent) {
                            x.detachEvent('on'+evt,handle);
                        }
                        //移除掉了事件把对应的数组设置为null
                        x.events[i]=null;
                    }
                    }
                }
            }
            else{
                console.log("没有绑定任何事件");
            }
        })
    }


    _window.MQuery.fn.trigger=function(funName){
        this.each(function(x){
            //检查是否存在该方法 存在则调用
            if(x[funName]){
                x[funName]();
            }
        })
    }
})(window);

测试代码

比如绑定键盘点击事件以及键盘点击事件

<!DOCTYPE html>
<html>
    <head>
        <title>mquery</title>
        <style>
            .p{
                width: 50px;
                height: 50px;
                border: 1px solid #ddd;
                margin-bottom: 20px;
                padding: 20px;
            }
        </style>
        <script type="text/javascript" src="../core/sizzle.js"></script>
        <script type="text/javascript" src="../core/mquery.js"></script>
        <script type="text/javascript" src="../core/event.js"></script>
    </head>
    <body>
        <p class="p">ppppp1</p>
        <p class="p">ppppp2</p>
        <button onclick="bind()">bind</button>
        <button onclick="unbind()">unbind</button>
        <button onclick="trigger()">trigger click event</button>
        <script type="text/javascript">
            var p = $("p");
            function showMsg(e){
                //console.log(this.innerHTML);
                console.log(e.keyCodeNames);
                console.log(e.buttons);
            }
            function click(e){
                console.log("click: "+this.innerHTML);
            }
            function mouseover(e){
                console.log("mouseover: "+this.innerHTML);
            }
            function bind(){
                console.log("bind keydown and mousedown event");
                p.bind("keydown",showMsg);
                p.bind("mousedown",showMsg);
                p.bind("click",click);
                p.bind("mouseover",mouseover);
            }
            function unbind(){
                p.unbind("keydown",showMsg)
                p.unbind("mousedown",showMsg);
                p.unbind("click",click);
                p.unbind("mouseover",mouseover);
                console.log("unbind keydown and mousedown event");
            }
            function trigger(){
                p.trigger("click");
            }
        </script>
    </body>
</html>

如果点击了某个元素或者按了键盘某个键则会显示该元素的innerHTML,然后显示按了哪个键或者点击了鼠标哪个键。

源代码下载:

mquery.rar

原文地址:https://www.cnblogs.com/xiaopi/p/3655579.html