Spiga

自制原生js工具库——Event篇

2008-05-07 21:28:34

源码

/* ******************************************************************* */
/*   EVENT FUNCTIONS                                                   */
/* ******************************************************************* */
​
var Event = (function() {
    var ev = {};
​
    //阻止事件冒泡
    ev.stopBubble = function(e) {
        // 如果传入了事件对象,那么就是非IE浏览器
        if (e)
        // 因此它支持W3C的stopPropagation
            e.stopPropagation();
        else
        // 否则,我们得使用IE的方式取消事件冒泡
            window.event.cancelBubble = true;
    };
​
    //防止发生默认浏览器行为
    ev.stopDefault = function(e) {
        // 防止默认浏览器行为(W3C)
        if (e) e.preventDefault();
​
        // IE中防止浏览器行为的捷径
        return false;
    };
    //
    // 由 Dean Edwards 所编写的addEvent/removeEvent 2005
    // 由Tino Zijdel整理
    // http://dean.edwards.name/weblog/2005/10/add-event/
​
    ev.addEvent = function(element, type, handler) {
        //为每个事件处理函数赋予一个独立的ID
        if (!handler.$$guid) handler.$$guid = ev.addEvent.guid++;
        //为元素建立一个事件类型的散列表
        if (!element.events) element.events = {};
        //为每个元素/事件建立一个事件处理函数的散列表
        var handlers = element.events[type];
        if (!handlers) {
            handlers = element.events[type] = {};
            //存储已有的事件处理函数
            if (element["on" + type]) {
                handlers[0] = element["on" + type];
            }
        }
        // 在散列表中存储该事件处理函数
        handlers[handler.$$guid] = handler;
        //赋予一个全局事件处理函数来处理所有工作
        element["on" + type] = ev.handleEvent;
    };
    // 创建独立ID的计数器
    ev.addEvent.guid = 1;
​
    ev.removeEvent = function(element, type, handler) {
        // 从散列表中删除事件处理函数
        if (element.events && element.events[type]) {
            delete element.events[type][handler.$$guid];
        }
    };
​
    ev.handleEvent = function(event) {
        var returnValue = true;
        // 获取事件对象
        event = event || ev.fixEvent(window.event);
        // 获取处理函数散列表的引用
        var handlers = this.events[event.type];
        //依次执行每个事件处理函数
        for (var i in handlers) {
            this.$$handleEvent = handlers[i];
            if (this.$$handleEvent(event) === false) {
                returnValue = false;
            }
        }
        return returnValue;
    };
​
    //增加一个IE事件对象的缺乏的方法
    ev.fixEvent = function(event) {
        // 增加W3C标准事件方法
        event.preventDefault = ev.fixEvent.preventDefault;
        event.stopPropagation = ev.fixEvent.stopPropagation;
        return event;
    };
    ev.fixEvent.preventDefault = function() {
        this.returnValue = false;
    };
    ev.fixEvent.stopPropagation = function() {
        this.cancelBubble = true;
    };
​
    //解决一个事件使用IE的window.event
    ev.resolve = function(e) {
        if (!defined(e) && defined(window.event)) {
            e = window.event;
        }
        return e;
    };
​
    // 获取鼠标事件
    ev.getMouseX = function( e ) {
        e = ev.resolve( e );
        if ( defined( e.pageX ) ) {
            return e.pageX;
        }
        if ( defined( e.clientX ) ) {
            return e.clientX+Screen.getScrollLeft();
        }
        return null;
    };
    ev.getMouseY = function( e ) {
        e = ev.resolve( e );
        if ( defined( e.pageY ) ) {
            return e.pageY;
        }
        if ( defined( e.clientY ) ) {
            return e.clientY+Screen.getScrollTop();
        }
        return null;
    };
​
    return ev;
})();

范例

function test_event(v,w)
{
    var btn = id("btnClick");
    Event.addEvent(btn, "click", _test);
    Event.removeEvent(btn, "click", _test);
    function _test() 
    {
        alert(v+w);
    }
    alert(Event.getMouseX());
    alert(Event.getMouseY());
}