簡単なonイベントバインディング

5987 ワード

簡単なonとoffの方法を実現します.
紹介:
  • Eventオブジェクト:
       funcList: {}, //  delegate         
       ieFuncList :{} //  ie      
  • Eventオブジェクトにおけるon,off方法は、主にEvent.addEvent,Event.delegatehandleという2つの方法
       Event.addEvent:      addEventListener      
       Event.delegateHandle:        ,         ,                      ,          
      
    
  • を呼び出す.
  • addEvent/offEvent:
        obj.addEventListener(type, fn, false);
        obj.removeEventListener(type, fn, false);
  • コード-Event.js
    /**
     * addEvent
     * author [email protected]
     */
    window.Event = {};
    var Event = {
    
        funcList: {}, //  delegate         
        ieFuncList: {}, //     ie      
    
    
        on: function(obj, selector, type, fn) {
            if (!obj || !selector) return false;
            var fnNew = Event.delegateHandle(obj, selector, fn);
            Event.addEvent(obj, type, fnNew);
            /*         Event.funcList,         */
            if (!Event.funcList[selector]) {
                Event.funcList[selector] = {};
            }
            if (!Event.funcList[selector][type]) {
                Event.funcList[selector][type] = {};
            }
    
            Event.funcList[selector][type][fn] = fnNew;
        },
    
        off: function(obj, selector, type, fn) {
            if (!obj || !selector || !Event.funcList[selector]) {
                return false;
            }
            var fnNew = Event.funcList[selector][type][fn];
            if (!fnNew) {
                return;
            }
    
            Event.offEvent(obj, type, fnNew);
            Event.funcList[selector][type][fn] = null;
        },
    
        delegateHandle: function(obj, selector, fn) {
            /*   delegate      ,       ,               */
            var func = function(event) {
                var event = event || window.event;
                var target = event.srcElement || event.target;
                var parent = target;
    
                function contain(item, elmName) {
                    if (elmName.split('#')[1]) { //by id
                        if (item.id && item.id === elmName.split('#')[1]) {
                            return true;
                        }
                    }
                    if (elmName.split('.')[1]) { //by class
                        if (hasClass(item, elmName.split('.')[1])) {
                            return true;
                        }
                    }
                    if (item.tagName == elmName.toUpperCase()) {
                        return true; //by tagname
                    }
                    return false;
                }
                while (parent) {
                    /*        ,  (selector)     。 */
                    if (obj == parent) {
                        return false; //       
                    }
                    if (contain(parent, selector)) {
    
                        fn.call(obj, event);
                        return;
                    }
                    parent = parent.parentNode;
                }
            };
            return func;
        },
        addEvent: function(target, type, fn) {
            if (!target) return false;
            var add = function(obj) {
                if (obj.addEventListener) {
    
                    obj.addEventListener(type, fn, false);
    
                } else {
                    // for ie
                    if (!Event.ieFuncList[obj]) Event.ieFuncList[obj] = {};
                    if (!Event.ieFuncList[obj][type]) Event.ieFuncList[obj][type] = {};
                    Event.ieFuncList[obj][type][fn] = function() {
                        fn.apply(obj, arguments);
                    };
                    obj.attachEvent("on" + type, Event.ieFuncList[obj][type][fn]);
                }
            }
            if (target.length >= 0 && target !== window && !target.tagName) {
                for (var i = 0, l = target.length; i < l; i++) {
                    add(target[i])
                }
            } else {
                add(target);
            }
        },
    
    
        offEvent: function(target, type, fn) {
            if (!target) return false;
            var remove = function(obj) {
                if (obj.addEventListener) {
                    obj.removeEventListener(type, fn, false);
    
                } else {
                    //for ie
                    if (!Event.ieFuncList[obj] || !Event.ieFuncList[obj][type] || !Event.ieFuncList[obj][type][fn]) {
                        return;
                    }
                    obj.detachEvent("on" + type, Event.ieFuncList[obj][type][fn], false);
                    Event.ieFuncList[obj][type][fn] = {};
                }
            }
            if (target.length >= 0 && target !== window && !target.tagName) {
                for (var i = 0, l = target.length; i < l; i++) {
                    remove(target[i])
                }
            } else {
                remove(target);
            }
        },
    
    };
    コード-DEMO. test

    Event

    (function(){ /* demo*/ var $id=function(id) { return document.getElementById(id) || id; } var outer = $id("content"), btn = $id("text"); Event.on(outer,'button',"click",add); Event.on(outer,'#unbind',"click",remove); // , var newbtn = document.createElement("button"); var node = document.createTextNode("new button"); newbtn.appendChild(node); outer.appendChild(newbtn); function add(){ var e = arguments[0] || window.event; var target = e.srcElement || e.target; console.log("target:",target); btn.innerHTML = target.innerHTML + ' ' + e.type; } function remove(){ Event.off(outer,'button',"click",add); Event.off(outer,'#unbind',"click",remove); } })();