• 模拟一个自己的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

  • 相关阅读:
    pycharm使用小技巧
    多线程的异常处理
    零星
    python的多线程 ThreadPoolExecutor
    零星
    python的轮询timer 和js的轮询setInterval
    fcitx 输入框纵向
    Gvim配置
    窗口,父窗口parentwindow,所有者窗口ownerwindow
    Request对象 --web浏览器向web服务端的请求
  • 原文地址:https://www.cnblogs.com/xiaopi/p/3655579.html
Copyright © 2020-2023  润新知