📄 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) { 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 {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), 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 { 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; // 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); 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; return false; } } // removed the wrapped handler delete listeners[index][this.WFN]; delete listeners[index][this.FN]; //listeners.splice(index, 1); listeners[index]=null; return true; }, /** * Returns the event's target element. Safari sometimes provides * a text node, and this is automatically resolved to the text * node's parent so that it behaves like other browsers. * @method getTarget * @param {Event} ev the event * @param {boolean} resolveTextNode when set to true the target's * parent will be returned if the target is a * text node. @deprecated, the text node is * now resolved automatically * @return {HTMLElement} the event's target * @static */ getTarget: function(ev, resolveTextNode) { var t = ev.target || ev.srcElement; return this.resolveTextNode(t); }, /** * In some cases, some browsers will return a text node inside * the actual element that was targeted. This normalizes the * return value for getTarget and getRelatedTarget. * @method resolveTextNode * @param {HTMLElement} node node to resolve * @return {HTMLElement} the normized node * @static */ resolveTextNode: function(node) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -