模擬一個本身的jquery(三) 事件

模擬bind方法與unbind方法

jquery的bind() 方法爲被選元素添加一個或多個事件處理程序,並規定事件發生時運行的函數。javascript

模擬的bind事件主要是針對ie與w3c事件模型的不一致提供一個統一的接口。而後再設置綁定事件的上下文爲觸發事件的元素,也就是在事件中可以經過this訪問到觸發事件的元素。html

unbind:移除掉綁定的方法。java

trigger:觸發某個事件:如$("#bt1").trigger("click") 則會觸發id爲bt1的點擊事件jquery

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,而後顯示按了哪一個鍵或者點擊了鼠標哪一個鍵。測試

源代碼下載:this

mquery.rarspa

相關文章
相關標籤/搜索