📄 event.js
字号:
* @return {boolean} true if the object is array-like and populated
* @private
*/
_isValidCollection: function(o) {
return ( o && // o is something
o.length && // o is indexed
typeof o != "string" && // o is not a string
!o.tagName && // o is not an HTML element
!o.alert && // o is not a window
typeof o[0] != "undefined" );
},
/**
* @private
* @property elCache
* DOM element cache
*/
elCache: {},
/**
* We cache elements bound by id because when the unload event
* fires, we can no longer use document.getElementById
* @method getEl
* @private
*/
getEl: function(id) {
return document.getElementById(id);
},
/**
* Clears the element cache
* @deprecated
* @private
*/
clearCache: function() { },
/**
* hook up any deferred listeners
* @method _load
* @private
*/
_load: function(e) {
loadComplete = true;
var EU = YAHOO.util.Event;
EU._simpleRemove(window, "load", EU._load);
},
/**
* Polling function that runs before the onload event fires,
* attempting to attach to DOM Nodes as soon as they are
* available
* @method _tryPreloadAttach
* @private
*/
_tryPreloadAttach: function() {
if (this.locked) {
return false;
}
this.locked = true;
// keep trying until after the page is loaded. We need to
// check the page load state prior to trying to bind the
// elements so that we can be certain all elements have been
// tested appropriately
var tryAgain = !loadComplete;
if (!tryAgain) {
tryAgain = (retryCount > 0);
}
// Delayed listeners
var stillDelayed = [];
for (var i=0,len=delayedListeners.length; i<len; ++i) {
var d = delayedListeners[i];
// There may be a race condition here, so we need to
// verify the array element is usable.
if (d) {
// el will be null if document.getElementById did not
// work
var el = this.getEl(d[this.EL]);
if (el) {
this.on(el, d[this.TYPE], d[this.FN],
d[this.SCOPE], d[this.ADJ_SCOPE]);
delete delayedListeners[i];
} else {
stillDelayed.push(d);
}
}
}
delayedListeners = stillDelayed;
// onAvailable
var notAvail = [];
for (i=0,len=onAvailStack.length; i<len ; ++i) {
var item = onAvailStack[i];
if (item) {
el = this.getEl(item.id);
if (el) {
var scope = (item.override) ? item.obj : el;
item.fn.call(scope, item.obj);
delete onAvailStack[i];
} else {
notAvail.push(item);
}
}
}
retryCount = (stillDelayed.length === 0 &&
notAvail.length === 0) ? 0 : retryCount - 1;
if (tryAgain) {
this.startTimeout();
}
this.locked = false;
return true;
},
/**
* Removes all listeners attached to the given element via addListener.
* Optionally, the node's children can also be purged.
* Optionally, you can specify a specific type of event to remove.
* @method purgeElement
* @param {HTMLElement} el the element to purge
* @param {boolean} recurse recursively purge this element's children
* as well. Use with caution.
* @param {string} sType optional type of listener to purge. If
* left out, all listeners will be removed
*/
purgeElement: function(el, recurse, sType) {
var elListeners = this.getListeners(el, sType);
if (elListeners) {
for (var i=0,len=elListeners.length; i<len ; ++i) {
var l = elListeners[i];
// can't use the index on the changing collection
//this.removeListener(el, l.type, l.fn, l.index);
this.removeListener(el, l.type, l.fn);
}
}
if (recurse && el && el.childNodes) {
for (i=0,len=el.childNodes.length; i<len ; ++i) {
this.purgeElement(el.childNodes[i], recurse, sType);
}
}
},
/**
* Returns all listeners attached to the given element via addListener.
* Optionally, you can specify a specific type of event to return.
* @method getListeners
* @param el {HTMLElement} the element to inspect
* @param sType {string} optional type of listener to return. If
* left out, all listeners will be returned
* @return {Object} the listener. Contains the following fields:
* type: (string) the type of event
* fn: (function) the callback supplied to addListener
* obj: (object) the custom object supplied to addListener
* adjust: (boolean) whether or not to adjust the default scope
* index: (int) its position in the Event util listener cache
*/
getListeners: function(el, sType) {
var elListeners = [];
if (listeners && listeners.length > 0) {
for (var i=0,len=listeners.length; i<len ; ++i) {
var l = listeners[i];
if ( l && l[this.EL] === el &&
(!sType || sType === l[this.TYPE]) ) {
elListeners.push({
type: l[this.TYPE],
fn: l[this.FN],
obj: l[this.SCOPE],
adjust: l[this.ADJ_SCOPE],
index: i
});
}
}
}
return (elListeners.length) ? elListeners : null;
},
/**
* Removes all listeners registered by pe.event. Called
* automatically during the unload event.
* @method _unload
* @private
*/
_unload: function(e) {
var EU = YAHOO.util.Event;
for (var i=0,len=unloadListeners.length; i<len; ++i) {
var l = unloadListeners[i];
if (l) {
var scope = (l[EU.ADJ_SCOPE]) ? l[EU.SCOPE]: window;
l[EU.FN].call(scope, EU.getEvent(e), l[EU.SCOPE] );
delete unloadListeners[i];
l=null;
}
}
if (listeners && listeners.length > 0) {
//for (i=0,len=listeners.length; i<len ; ++i) {
var j = listeners.length;
while (j) {
var index = j-1;
l = listeners[index];
if (l) {
EU.removeListener(l[EU.EL], l[EU.TYPE],
l[EU.FN], index);
}
l=null;
j = j - 1;
}
EU.clearCache();
}
for (i=0,len=legacyEvents.length; i<len; ++i) {
// dereference the element
delete legacyEvents[i][0];
// delete the array item
delete legacyEvents[i];
}
EU._simpleRemove(window, "unload", EU._unload);
},
/**
* Returns scrollLeft
* @method _getScrollLeft
* @private
*/
_getScrollLeft: function() {
return this._getScroll()[1];
},
/**
* Returns scrollTop
* @method _getScrollTop
* @private
*/
_getScrollTop: function() {
return this._getScroll()[0];
},
/**
* Returns the scrollTop and scrollLeft. Used to calculate the
* pageX and pageY in Internet Explorer
* @method _getScroll
* @private
*/
_getScroll: function() {
var dd = document.documentElement, db = document.body;
if (dd && (dd.scrollTop || dd.scrollLeft)) {
return [dd.scrollTop, dd.scrollLeft];
} else if (db) {
return [db.scrollTop, db.scrollLeft];
} else {
return [0, 0];
}
},
/**
* Adds a DOM event directly without the caching, cleanup, scope adj, etc
*
* @param el the elment to bind the handler to
* @param {string} sType the type of event handler
* @param {function} fn the callback to invoke
* @param {boolen} capture or bubble phase
* @private
*/
_simpleAdd: function (el, sType, fn, capture) {
if (el.addEventListener) {
el.addEventListener(sType, fn, (capture));
} else if (el.attachEvent) {
el.attachEvent("on" + sType, fn);
}
},
/**
* Basic remove listener
*
* @param el the elment to bind the handler to
* @param {string} sType the type of event handler
* @param {function} fn the callback to invoke
* @param {boolen} capture or bubble phase
* @private
*/
_simpleRemove: function (el, sType, fn, capture) {
if (el.removeEventListener) {
el.removeEventListener(sType, fn, (capture));
} else if (el.detachEvent) {
el.detachEvent("on" + sType, fn);
}
}
};
} ();
/**
* YAHOO.util.Event.on is an alias for addListener
* @method on
* @see addListener
*/
YAHOO.util.Event.on = YAHOO.util.Event.addListener;
if (document && document.body) {
YAHOO.util.Event._load();
} else {
YAHOO.util.Event._simpleAdd(window, "load", YAHOO.util.Event._load);
}
YAHOO.util.Event._simpleAdd(window, "unload", YAHOO.util.Event._unload);
YAHOO.util.Event._tryPreloadAttach();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -