代码改变世界

把javascript event事件封装了下,兼容大多数浏览器【已修改】

2011-10-11 11:43  sniper007  阅读(173)  评论(0)    收藏  举报

var extend = function(destination,source){
    for(var o in source)
        destination[o] = source[o];
    return destination;
};

(function(){
var Event = {},
    Cache,
    cache = [],
    _onunloadHandlerRegistered;

function addEvent(element, eventType, handler){
    if (element.addEventListener) {
        element.addEventListener(eventType, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + eventType, handler);
    } else {
        element["on" + eventType] = handler;
    }    
}

function removeEvent(element, eventType, handler){
    if(element.removeEventListener) {
        element.removeEventListener(eventType, handler, false);
    }else if(element.detachEvent) {
        element.detachEvent("on" + eventType, handler);
    }else
        element["on" + eventType] = null;
    }
}

var getUUID = (function(){
    var _counter = 35;
    return function(){
        return "tigerEvent0" + _counter++;
    }    
})();

function getDoc(element){
    return element.ownerDocument || element.document || ((element.defaultView || element.window) && element) || document;
};

function add(element, eventType, handler, list){
    var    d = getDoc(element),
        w = cache,
        id = getUUID();
    
    w[id] = list;
    if(!element._handlers){
        element._handlers = [];
    }
    element._handlers.push(id);    
}

function get(element, eventType, handler, isSignal){
    var handlers = element._handlers,
        returnVal = -1,
        returnObj = null,
        isFinished = true;
    if(!handlers){
        return -1;
    }
    var d = getDoc(element),
        w = cache;
    for(var i = handlers.length - 1; i >= 0; i--){
        var handlerId = handlers[i],
            h = w[handlerId];
        if(h.eventType == eventType && h.handler == handler){
            returnVal = i;
            returnObj = h;
            isFinished = false;
            break;
        }
    }
    
    if(isFinished){
        return;
    }
    
    if(!!isSignal){
        return [returnVal, returnObj];
    }else{
        return -1;
    }
}

function remove(element, eventType, handler){
    var i = get(element, eventType, handler);
    if(i == -1){
        return;
    }
    var    d = getDoc(element),
        w = cache,
        handlerId = element._handlers[i],
        h = w[handlerId];
    element._handlers.splice(i, 1);
    delete cache[handlerId];    
}

function on(element, eventType, handler){
    var i = get(element, eventType, handler);
    if(i != -1){
        return;
    }    
    function wrappedHandler(e){
        e = window.event || e;
        var event = fixed(e);
        event._event = e;
        handler.call(element, event);
    }
    
    
    var h = {
        element : element,
        eventType : eventType,
        handler : handler,
        wrappedHandler : wrappedHandler
    };
    add(element, eventType, handler, h);
    addEvent(element, eventType, h.wrappedHandler);
    
    if(!_onunloadHandlerRegistered){
        _onunloadHandlerRegistered = true;
        if(window.attachEvent){
            window.attachEvent("onunload", removeAllHandlers);
        }
    }    
}

function un(element, eventType, handler){
    var i = get(element, eventType, handler);
    if(i != -1){
        return;
    }    
    removeEvent(element, eventType, get(element, eventType, handler, true)[1].wrappedHandler);    
    element._handlers.splice(i, 1);
    remove(element, eventType, handler);    
}

function fixed(event){
    if ( !event.target ) {
        event.target = event.srcElement || document;
    }
    if ( event.target.nodeType === 3 ) {
        event.target = event.target.parentNode;
    }

    if ( !event.relatedTarget && event.fromElement ) {
        event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
    }
    
    if ( event.pageX == null && event.clientX != null ) {
        var eventDocument = event.target.ownerDocument || document,
            doc = eventDocument.documentElement,
            body = eventDocument.body;

        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
    }

    if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
        event.which = event.charCode != null ? event.charCode : event.keyCode;
    }

    if ( !event.metaKey && event.ctrlKey ) {
        event.metaKey = event.ctrlKey;
    }
    if ( !event.which && event.button !== undefined ) {
        event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
    }

    return event;
}

function fire(element, eventType){
    if (document.dispatchEvent) {
        var evt = null,
            doc = getDoc(element);
        if (/mouse|click/i.test(eventType)) {
            evt = doc.createEvent('MouseEvents');
            evt.initMouseEvent(eventType, truetrue, doc.defaultView, 1, 0, 0, 0, 0, falsefalsefalsefalse, 0, null);
        } else {
            evt = doc.createEvent('Events');
            evt.initEvent(eventType, truetrue, doc.defaultView);
        }
        element.dispatchEvent(evt);
    }else{
        element.fireEvent('on' + eventType);
    }    
}

/*
防止IE内存溢出
*/

function removeAllHandlers(){
    var w = cache;
    for(var id in w){
        var h = w[id];
        if(h.element.detachEvent){
            h.element.detachEvent("on" + h.eventType, h.wrappedHandler);            
        }
        delete w[id];
    }    
}

extend(Event, {
    on : on,
    un : un,
    fire : fire,
    cache : cache,
    addEvent : addEvent,
    removeEvent : removeEvent,
    _onunloadHandlerRegistered : _onunloadHandlerRegistered
});

window.Event = Event;
})();




var edit = document.getElementById("edit");
var del = document.getElementById("del");
var fire = document.getElementById("fire");
Event.on(del, "click", function(e){
    Event.un(fire, "click", handleFire);
});
Event.on(fire, "click", handleFire);

function handleFire(){
    alert(this);
}