zoukankan      html  css  js  c++  java
  • javascript的事件触发和接收源码

    define(function(require,exports,module){
    
        var Events=function(){
            var array = [];
            var push = array.push;
            var slice = array.slice;
            var splice = array.splice;
            var Events  = {
    
                // Bind an event to a `callback` function. Passing `"all"` will bind
                // the callback to all events fired.
                on: function(name, callback, context) {
                    if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
                    this._events || (this._events = {});
                    var events = this._events[name] || (this._events[name] = []);
                    events.push({callback: callback, context: context, ctx: context || this});
                    return this;
                },
    
                // Bind an event to only be triggered a single time. After the first time
                // the callback is invoked, it will be removed.
                once: function(name, callback, context) {
                    if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
                    var self = this;
                    var once = _.once(function() {
                        self.off(name, once);
                        callback.apply(this, arguments);
                    });
                    once._callback = callback;
                    return this.on(name, once, context);
                },
    
                // Remove one or many callbacks. If `context` is null, removes all
                // callbacks with that function. If `callback` is null, removes all
                // callbacks for the event. If `name` is null, removes all bound
                // callbacks for all events.
                off: function(name, callback, context) {
                    var retain, ev, events, names, i, l, j, k;
                    if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
                    if (!name && !callback && !context) {
                        this._events = {};
                        return this;
                    }
    
                    names = name ? [name] : _.keys(this._events);
                    for (i = 0, l = names.length; i < l; i++) {
                        name = names[i];
                        if (events = this._events[name]) {
                            this._events[name] = retain = [];
                            if (callback || context) {
                                for (j = 0, k = events.length; j < k; j++) {
                                    ev = events[j];
                                    if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
                                        (context && context !== ev.context)) {
                                        retain.push(ev);
                                    }
                                }
                            }
                            if (!retain.length) delete this._events[name];
                        }
                    }
    
                    return this;
                },
    
                // Trigger one or many events, firing all bound callbacks. Callbacks are
                // passed the same arguments as `trigger` is, apart from the event name
                // (unless you're listening on `"all"`, which will cause your callback to
                // receive the true name of the event as the first argument).
                trigger: function(name) {
                    if (!this._events) return this;
                    var args = slice.call(arguments, 1);
                    if (!eventsApi(this, 'trigger', name, args)) return this;
                    var events = this._events[name];
                    var allEvents = this._events.all;
                    if (events) triggerEvents(events, args);
                    if (allEvents) triggerEvents(allEvents, arguments);
                    return this;
                },
    
                // Tell this object to stop listening to either specific events ... or
                // to every object it's currently listening to.
                stopListening: function(obj, name, callback) {
                    var listeners = this._listeners;
                    if (!listeners) return this;
                    var deleteListener = !name && !callback;
                    if (typeof name === 'object') callback = this;
                    if (obj) (listeners = {})[obj._listenerId] = obj;
                    for (var id in listeners) {
                        listeners[id].off(name, callback, this);
                        if (deleteListener) delete this._listeners[id];
                    }
                    return this;
                }
    
            };
    
            // Regular expression used to split event strings.
            var eventSplitter = /s+/;
    
            // Implement fancy features of the Events API such as multiple event
            // names `"change blur"` and jQuery-style event maps `{change: action}`
            // in terms of the existing API.
            var eventsApi = function(obj, action, name, rest) {
                if (!name) return true;
    
                // Handle event maps.
                if (typeof name === 'object') {
                    for (var key in name) {
                        obj[action].apply(obj, [key, name[key]].concat(rest));
                    }
                    return false;
                }
    
                // Handle space separated event names.
                if (eventSplitter.test(name)) {
                    var names = name.split(eventSplitter);
                    for (var i = 0, l = names.length; i < l; i++) {
                        obj[action].apply(obj, [names[i]].concat(rest));
                    }
                    return false;
                }
    
                return true;
            };
    
            // A difficult-to-believe, but optimized internal dispatch function for
            // triggering events. Tries to keep the usual cases speedy (most internal
            // Backbone events have 3 arguments).
            var triggerEvents = function(events, args) {
                var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
                switch (args.length) {
                    case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
                    case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
                    case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
                    case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
                    default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
                }
            };
    
    
            // Aliases for backwards compatibility.
            Events.bind   = Events.on;
            Events.unbind = Events.off;
            return Events;
        }()
    
    module.exports=Events
    
    })
  • 相关阅读:
    Directx11教程(21) 修正程序最小化异常bug
    Directx教程(28) 简单的光照模型(7)
    Directx教程(22) 简单的光照模型(1)
    Directx教程(26) 简单的光照模型(5)
    Directx教程(25) 简单的光照模型(4)
    finit 1.5 发布,/sbin/init 的服务器监控器
    MySQL 8小时问题
    DataCleaner 3.0.1 发布,数据质量分析管理
    dedecms调用其它栏目列表
    ReportPlus:在iPad上创建和使用仪表盘及报表
  • 原文地址:https://www.cnblogs.com/caoke/p/4058923.html
Copyright © 2011-2022 走看看