📄 event.js
字号:
* @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
*
*/
onAvailable: function(p_id, p_fn, p_obj, p_override) {
onAvailStack.push( { id: p_id,
fn: p_fn,
obj: p_obj,
override: p_override } );
retryCount = this.POLL_RETRYS;
this.startTimeout(0);
// this._tryPreloadAttach();
},
/**
* Appends an event handler
*
* @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} oScope An arbitrary object that will be
* passed as a parameter to the handler
* @param {boolean} bOverride 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.
*/
addListener: function(el, sType, fn, oScope, bOverride) {
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,
oScope,
bOverride) && 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 (loadComplete && oEl) {
el = oEl;
} else {
// defer adding the event until onload fires
this.addDelayedListener(el,
sType,
fn,
oScope,
bOverride);
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 && oScope !== this) {
unloadListeners[unloadListeners.length] =
[el, sType, fn, oScope, bOverride];
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 = (bOverride) ? oScope : el;
// wrap the function so we can return the oScope object when
// the event fires;
var wrappedFn = function(e) {
return fn.call(scope, YAHOO.util.Event.getEvent(e),
oScope);
};
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);
if (legacyIndex == -1) {
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);
// DOM2 Event model
} else if (el.addEventListener) {
el.addEventListener(sType, wrappedFn, false);
// IE
} else if (el.attachEvent) {
el.attachEvent("on" + sType, wrappedFn);
}
return true;
},
/**
* Shorthand for YAHOO.util.Event.addListener
* @type function
*/
// on: this.addListener,
/**
* When using legacy events, the handler is routed to this object
* so we can fire our custom listener stack.
* @private
*/
fireLegacyEvent: function(e, legacyIndex) {
var ok = true;
var le = legacyHandlers[legacyIndex];
for (var i=0,len=le.length; i<len; ++i) {
var index = le[i];
if (index) {
var li = listeners[index];
if ( li && li[this.WFN] ) {
var scope = li[this.ADJ_SCOPE];
var ret = li[this.WFN].call(scope, e);
ok = (ok && ret);
} else {
// This listener was removed, so delete it from
// the array
delete le[i];
}
}
}
return ok;
},
/**
* Returns the legacy event index that matches the supplied
* signature
* @private
*/
getLegacyIndex: function(el, sType) {
/*
for (var i=0,len=legacyEvents.length; i<len; ++i) {
var le = legacyEvents[i];
if (le && le[0] === el && le[1] === sType) {
return i;
}
}
return -1;
*/
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.
* @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
*
* @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
* @return {boolean} true if the unbind was successful, false
* otherwise
*/
removeListener: function(el, sType, fn, index) {
if (!fn || !fn.call) {
return false;
}
// 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 (var i=0,len=el.length; i<len; ++i) {
ok = ( this.removeListener(el[i], sType, fn) && ok );
}
return ok;
}
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) {
delete unloadListeners[i];
return true;
}
}
return false;
}
var cacheItem = null;
if ("undefined" == typeof index) {
index = this._getCacheIndex(el, sType, fn);
}
if (index >= 0) {
cacheItem = listeners[index];
}
if (!el || !cacheItem) {
return false;
}
if (el.removeEventListener) {
el.removeEventListener(sType, cacheItem[this.WFN], false);
} else if (el.detachEvent) {
el.detachEvent("on" + sType, cacheItem[this.WFN]);
}
// removed the wrapped handler
delete listeners[index][this.WFN];
delete listeners[index][this.FN];
delete listeners[index];
return true;
},
/**
* Returns the event's target element
* @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
*/
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.
* @param {HTMLElement} node to resolve
* @return the normized node
*/
resolveTextNode: function(node) {
if (node && node.nodeName &&
"#TEXT" == node.nodeName.toUpperCase()) {
return node.parentNode;
} else {
return node;
}
},
/**
* Returns the event's pageX
* @param {Event} ev the event
* @return {int} the event's pageX
*/
getPageX: function(ev) {
var x = ev.pageX;
if (!x && 0 !== x) {
x = ev.clientX || 0;
if ( this.isIE ) {
x += this._getScrollLeft();
}
}
return x;
},
/**
* Returns the event's pageY
* @param {Event} ev the event
* @return {int} the event's pageY
*/
getPageY: function(ev) {
var y = ev.pageY;
if (!y && 0 !== y) {
y = ev.clientY || 0;
if ( this.isIE ) {
y += this._getScrollTop();
}
}
return y;
},
/**
* Returns the pageX and pageY properties as an indexed array.
* @type int[]
*/
getXY: function(ev) {
return [this.getPageX(ev), this.getPageY(ev)];
},
/**
* Returns the event's related target
* @param {Event} ev the event
* @return {HTMLElement} the event's relatedTarget
*/
getRelatedTarget: function(ev) {
var t = ev.relatedTarget;
if (!t) {
if (ev.type == "mouseout") {
t = ev.toElement;
} else if (ev.type == "mouseover") {
t = ev.fromElement;
}
}
return this.resolveTextNode(t);
},
/**
* Returns the time of the event. If the time is not included, the
* event is modified using the current time.
* @param {Event} ev the event
* @return {Date} the time of the event
*/
getTime: function(ev) {
if (!ev.time) {
var t = new Date().getTime();
try {
ev.time = t;
} catch(e) {
// can't set the time property
return t;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -