📄 event.js
字号:
* @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|object} p_override If set to true, p_fn will execute * in the scope of p_obj. If an object, p_fn will * exectute in the scope of that object * * @static */ onContentReady: function(p_id, p_fn, p_obj, p_override) { this.onAvailable(p_id, p_fn, p_obj, p_override, true); }, /** * Executes the supplied callback when the DOM is first usable. This * will execute immediately if called after the DOMReady event has * fired. @todo the DOMContentReady event does not fire when the * script is dynamically injected into the page. This means the * DOMReady custom event will never fire in FireFox or Opera when the * library is injected. It _will_ fire in Safari, and the IE * implementation would allow for us to fire it if the defered script * is not available. We want this to behave the same in all browsers. * Is there a way to identify when the script has been injected * instead of included inline? Is there a way to know whether the * window onload event has fired without having had a listener attached * to it when it did so? * * <p>The callback is a CustomEvent, so the signature is:</p> * <p>type <string>, args <array>, customobject <object></p> * <p>For DOMReady events, there are no fire argments, so the * signature is:</p> * <p>"DOMReady", [], obj</p> * * * @method onDOMReady * * @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|object} p_scope If set to true, p_fn will execute * in the scope of p_obj, if set to an object it * will execute in the scope of that object * * @static */ onDOMReady: function(p_fn, p_obj, p_override) { if (this.DOMReady) { setTimeout(function() { var s = window; if (p_override) { if (p_override === true) { s = p_obj; } else { s = p_override; } } p_fn.call(s, "DOMReady", [], p_obj); }, 0); } else { this.DOMReadyEvent.subscribe(p_fn, p_obj, p_override); } }, /** * Appends an event handler * * @method addListener * * @param {String|HTMLElement|Array|NodeList} el An id, an element * reference, or a collection of ids and/or elements to assign the * listener 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|object} override If true, the obj passed in becomes * the execution scope of the listener. If an * object, this object becomes the execution * scope. * @return {Boolean} True if the action was successful or defered, * false if one or more of the elements * could not have the listener attached, * or if the operation throws an exception. * @static */ addListener: function(el, sType, fn, obj, override) { if (!fn || !fn.call) {// throw new TypeError(sType + " addListener call failed, callback undefined"); 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 (YAHOO.lang.isString(el)) { 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, el), obj); }; var li = [el, sType, fn, wrappedFn, scope, obj, override]; 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 { try { this._simpleAdd(el, sType, wrappedFn, false); } catch(ex) { // handle an error trying to attach an event. If it fails // we need to clean up the cache this.lastError = ex; this.removeListener(el, sType, fn); return 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,le,lh,li,scope,ret; lh = legacyHandlers[legacyIndex]; for (var i=0,len=lh.length; i<len; ++i) { li = lh[i]; if ( li && li[this.WFN] ) { scope = li[this.ADJ_SCOPE]; ret = li[this.WFN].call(scope, e); ok = (ok && ret); } } // Fire the original handler if we replaced one. We fire this // after the other events to keep stopPropagation/preventDefault // that happened in the DOM0 handler from touching our DOM2 // substitute le = legacyEvents[legacyIndex]; if (le && le[2]) { le[2](e); } 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. Currently this is limited to old * Safari browsers with a broken preventDefault * @method useLegacyEvent * @static * @private */ useLegacyEvent: function(el, sType) { if (this.webkit && ("click"==sType || "dblclick"==sType)) { var v = parseInt(this.webkit, 10); if (!isNaN(v) && v<418) { return true; } } return false; }, /** * Removes an event listener * * @method removeListener * * @param {String|HTMLElement|Array|NodeList} el An id, an element * reference, or a collection of ids and/or elements to remove * the listener from. * @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, li; // 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++) { li = unloadListeners[i]; if (li && li[0] == el && li[1] == sType && li[2] == fn) { //unloadListeners.splice(i, 1); unloadListeners[i]=null; return true; } } return false; } var cacheItem = null; // The index is a hidden parameter; needed to remove it from // the method signature because it was tempting users to // try and take advantage of it, which is not possible. var index = arguments[3]; if ("undefined" === typeof index) { index = this._getCacheIndex(el, sType, fn); } if (index >= 0) { cacheItem = listeners[index]; } if (!el || !cacheItem) { return false; } if (this.useLegacyEvent(el, sType)) { var legacyIndex = this.getLegacyIndex(el, sType); var llist = legacyHandlers[legacyIndex]; if (llist) { for (i=0, len=llist.length; i<len; ++i) { li = llist[i]; if (li && li[this.EL] == el && li[this.TYPE] == sType && li[this.FN] == fn) { //llist.splice(i, 1); llist[i]=null; break; } } } } else { try { this._simpleRemove(el, sType, cacheItem[this.WFN], false); } catch(ex) { this.lastError = ex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -