event.js

来自「国外很不错的一个开源OA系统Group-Office」· JavaScript 代码 · 共 1,739 行 · 第 1/4 页

JS
1,739
字号
         */        var onAvailStack = [];        /**         * Lookup table for legacy events         * @property legacyMap         * @static         * @private         */        var legacyMap = [];        /**         * Counter for auto id generation         * @property counter         * @static         * @private         */        var counter = 0;        return { // PREPROCESS            /**             * The number of times we should look for elements that are not             * in the DOM at the time the event is requested after the document             * has been loaded.  The default is 200@amp;50 ms, so it will poll             * for 10 seconds or until all outstanding handlers are bound             * (whichever comes first).             * @property POLL_RETRYS             * @type int             * @static             * @final             */            POLL_RETRYS: 200,            /**             * The poll interval in milliseconds             * @property POLL_INTERVAL             * @type int             * @static             * @final             */            POLL_INTERVAL: 20,            /**             * Element to bind, int constant             * @property EL             * @type int             * @static             * @final             */            EL: 0,            /**             * Type of event, int constant             * @property TYPE             * @type int             * @static             * @final             */            TYPE: 1,            /**             * Function to execute, int constant             * @property FN             * @type int             * @static             * @final             */            FN: 2,            /**             * Function wrapped for scope correction and cleanup, int constant             * @property WFN             * @type int             * @static             * @final             */            WFN: 3,            /**             * Object passed in by the user that will be returned as a              * parameter to the callback, int constant             * @property OBJ             * @type int             * @static             * @final             */            OBJ: 3,            /**             * Adjusted scope, either the element we are registering the event             * on or the custom object passed in by the listener, int constant             * @property ADJ_SCOPE             * @type int             * @static             * @final             */            ADJ_SCOPE: 4,            /**             * Safari detection is necessary to work around the preventDefault             * bug that makes it so you can't cancel a href click from the              * handler.  There is not a capabilities check we can use here.             * @property isSafari             * @private             * @static             */            isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),            /**             * IE detection needed to properly calculate pageX and pageY.               * capabilities checking didn't seem to work because another              * browser that does not provide the properties have the values              * calculated in a different manner than IE.             * @property isIE             * @private             * @static             */            isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) &&                     navigator.userAgent.match(/msie/gi)),            /**             * poll handle             * @property _interval             * @private             */            _interval: null,            /**             * @method startInterval             * @static             * @private             */            startInterval: function() {                if (!this._interval) {                    var self = this;                    var callback = function() { self._tryPreloadAttach(); };                    this._interval = setInterval(callback, this.POLL_INTERVAL);                    // this.timeout = setTimeout(callback, i);                }            },            /**             * Executes the supplied callback when the item with the supplied             * id is found.  This is meant to be used to execute behavior as             * soon as possible as the page loads.  If you use this after the             * initial page load it will poll for a fixed time for the element.             * The number of times it will poll and the frequency are             * configurable.  By default it will poll for 10 seconds.             *             * @method onAvailable             *             * @param {string}   p_id the id of the element to look for.             * @param {function} p_fn what to execute when the element is found.             * @param {object}   p_obj an optional object to be passed back as             *                   a parameter to p_fn.             * @param {boolean}  p_override If set to true, p_fn will execute             *                   in the scope of p_obj             *             * @static             */            onAvailable: function(p_id, p_fn, p_obj, p_override) {                onAvailStack.push( { id:         p_id,                                      fn:         p_fn,                                      obj:        p_obj,                                      override:   p_override,                                      checkReady: false    } );                retryCount = this.POLL_RETRYS;                this.startInterval();            },            /**             * Works the same way as onAvailable, but additionally checks the             * state of sibling elements to determine if the content of the             * available element is safe to modify.             *             * @method onContentReady             *             * @param {string}   p_id the id of the element to look for.             * @param {function} p_fn what to execute when the element is ready.             * @param {object}   p_obj an optional object to be passed back as             *                   a parameter to p_fn.             * @param {boolean}  p_override If set to true, p_fn will execute             *                   in the scope of p_obj             *             * @static             */            onContentReady: function(p_id, p_fn, p_obj, p_override) {                onAvailStack.push( { id:         p_id,                                      fn:         p_fn,                                      obj:        p_obj,                                      override:   p_override,                                     checkReady: true      } );                retryCount = this.POLL_RETRYS;                this.startInterval();            },            /**             * Appends an event handler             *             * @method addListener             *             * @param {Object}   el        The html element to assign the              *                             event to             * @param {String}   sType     The type of event to append             * @param {Function} fn        The method the event invokes             * @param {Object}   obj    An arbitrary object that will be              *                             passed as a parameter to the handler             * @param {boolean}  override  If true, the obj passed in becomes             *                             the execution scope of the listener             * @return {boolean} True if the action was successful or defered,             *                        false if one or more of the elements              *                        could not have the event bound to it.             * @static             */            addListener: function(el, sType, fn, obj, override) {                if (!fn || !fn.call) {                    return false;                }                // The el argument can be an array of elements or element ids.                if ( this._isValidCollection(el)) {                    var ok = true;                    for (var i=0,len=el.length; i<len; ++i) {                        ok = this.on(el[i],                                        sType,                                        fn,                                        obj,                                        override) && ok;                    }                    return ok;                } else if (typeof el == "string") {                    var oEl = this.getEl(el);                    // If the el argument is a string, we assume it is                     // actually the id of the element.  If the page is loaded                    // we convert el to the actual element, otherwise we                     // defer attaching the event until onload event fires                    // check to see if we need to delay hooking up the event                     // until after the page loads.                    if (oEl) {                        el = oEl;                    } else {                        // defer adding the event until the element is available                        this.onAvailable(el, function() {                           YAHOO.util.Event.on(el, sType, fn, obj, override);                        });                        return true;                    }                }                // Element should be an html element or an array if we get                 // here.                if (!el) {                    return false;                }                // we need to make sure we fire registered unload events                 // prior to automatically unhooking them.  So we hang on to                 // these instead of attaching them to the window and fire the                // handles explicitly during our one unload event.                if ("unload" == sType && obj !== this) {                    unloadListeners[unloadListeners.length] =                            [el, sType, fn, obj, override];                    return true;                }                // if the user chooses to override the scope, we use the custom                // object passed in, otherwise the executing scope will be the                // HTML element that the event is registered on                var scope = el;                if (override) {                    if (override === true) {                        scope = obj;                    } else {                        scope = override;                    }                }                // wrap the function so we can return the obj object when                // the event fires;                var wrappedFn = function(e) {                        return fn.call(scope, YAHOO.util.Event.getEvent(e),                                 obj);                    };                var li = [el, sType, fn, wrappedFn, scope];                var index = listeners.length;                // cache the listener so we can try to automatically unload                listeners[index] = li;                if (this.useLegacyEvent(el, sType)) {                    var legacyIndex = this.getLegacyIndex(el, sType);                    // Add a new dom0 wrapper if one is not detected for this                    // element                    if ( legacyIndex == -1 ||                                 el != legacyEvents[legacyIndex][0] ) {                        legacyIndex = legacyEvents.length;                        legacyMap[el.id + sType] = legacyIndex;                        // cache the signature for the DOM0 event, and                         // include the existing handler for the event, if any                        legacyEvents[legacyIndex] =                             [el, sType, el["on" + sType]];                        legacyHandlers[legacyIndex] = [];                        el["on" + sType] =                             function(e) {                                YAHOO.util.Event.fireLegacyEvent(                                    YAHOO.util.Event.getEvent(e), legacyIndex);                            };                    }                    // add a reference to the wrapped listener to our custom                    // stack of events                    //legacyHandlers[legacyIndex].push(index);                    legacyHandlers[legacyIndex].push(li);                } else {                    this._simpleAdd(el, sType, wrappedFn, false);                }                return true;                            },            /**             * When using legacy events, the handler is routed to this object             * so we can fire our custom listener stack.             * @method fireLegacyEvent             * @static             * @private             */            fireLegacyEvent: function(e, legacyIndex) {                var ok = true;                var le = legacyHandlers[legacyIndex];                for (var i=0,len=le.length; i<len; ++i) {                    var li = le[i];                    if ( li && li[this.WFN] ) {                        var scope = li[this.ADJ_SCOPE];                        var ret = li[this.WFN].call(scope, e);                        ok = (ok && ret);                    }                }                return ok;            },            /**             * Returns the legacy event index that matches the supplied              * signature             * @method getLegacyIndex             * @static             * @private             */            getLegacyIndex: function(el, sType) {                var key = this.generateId(el) + sType;                if (typeof legacyMap[key] == "undefined") {                     return -1;                } else {                    return legacyMap[key];                }            },            /**             * Logic that determines when we should automatically use legacy             * events instead of DOM2 events.             * @method useLegacyEvent             * @static             * @private             */            useLegacyEvent: function(el, sType) {                if (!el.addEventListener && !el.attachEvent) {                    return true;                } else if (this.isSafari) {                    if ("click" == sType || "dblclick" == sType) {                        return true;                    }                }                return false;            },                                /**             * Removes an event handler             *             * @method removeListener             *             * @param {Object} el the html element or the id of the element to              * assign the event to.             * @param {String} sType the type of event to remove.             * @param {Function} fn the method the event invokes.  If fn is             * undefined, then all event handlers for the type of event are              * removed.             * @return {boolean} true if the unbind was successful, false              * otherwise.             * @static             */            removeListener: function(el, sType, fn) {                var i, len;                // The el argument can be a string                if (typeof el == "string") {                    el = this.getEl(el);                // The el argument can be an array of elements or element ids.                } else if ( this._isValidCollection(el)) {                    var ok = true;                    for (i=0,len=el.length; i<len; ++i) {                        ok = ( this.removeListener(el[i], sType, fn) && ok );                    }                    return ok;                }                if (!fn || !fn.call) {                    //return false;                    return this.purgeElement(el, false, sType);                }                if ("unload" == sType) {                    for (i=0, len=unloadListeners.length; i<len; i++) {                        var li = unloadListeners[i];                        if (li &&                             li[0] == el &&                             li[1] == sType &&                             li[2] == fn) {                                unloadListeners.splice(i, 1);                                return true;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?