Una muy buena pregunta ... Estaba intrigado así que hice un poco de excavación; para aquellos que están interesados, aquí es donde fui, y lo que se me ocurrió.
En cuanto al código fuente de jQuery 1.4.2 Vi este bloque entre las líneas 2361 y 2392:
jQuery.each(["bind", "one"], function(i, name) {
jQuery.fn[ name ] = function(type, data, fn) {
// Handle object literals
if (typeof type === "object") {
for (var key in type) {
this[ name ](key, data, type[key], fn);
}
return this;
}
if (jQuery.isFunction(data)) {
fn = data;
data = undefined;
}
var handler = name === "one" ? jQuery.proxy(fn, function(event) {
jQuery(this).unbind(event, handler);
return fn.apply(this, arguments);
}) : fn;
if (type === "unload" && name !== "one") {
this.one(type, data, fn);
} else {
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.add(this[i], type, handler, data);
}
}
return this;
};
});
Hay una mucho de cosas interesantes que hacer aquí, pero la parte que nos interesa es entre las líneas 2384 y 2388:
else {
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.add(this[i], type, handler, data);
}
}
Cada vez que llamamos bind()
o one()
que en realidad está haciendo una llamada a jQuery.event.add()
... así que vamos a echar un vistazo a eso (líneas 1557 a 1672, si está interesado)
add: function(elem, types, handler, data) {
// ... snip ...
var handleObjIn, handleObj;
if (handler.handler) {
handleObjIn = handler;
handler = handleObjIn.handler;
}
// ... snip ...
// Init the element's event structure
var elemData = jQuery.data(elem);
// ... snip ...
var events = elemData.events = elemData.events || {},
eventHandle = elemData.handle, eventHandle;
if (!eventHandle) {
elemData.handle = eventHandle = function() {
// Handle the second event of a trigger and when
// an event is called after a page has unloaded
return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
jQuery.event.handle.apply(eventHandle.elem, arguments) :
undefined;
};
}
// ... snip ...
// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
types = types.split(" ");
var type, i = 0, namespaces;
while ((type = types[ i++ ])) {
handleObj = handleObjIn ?
jQuery.extend({}, handleObjIn) :
{ handler: handler, data: data };
// Namespaced event handlers
^
|
// There is is! Even marked with a nice handy comment so you couldn't miss it
// (Unless of course you are not looking for it ... as I wasn't)
if (type.indexOf(".") > -1) {
namespaces = type.split(".");
type = namespaces.shift();
handleObj.namespace = namespaces.slice(0).sort().join(".");
} else {
namespaces = [];
handleObj.namespace = "";
}
handleObj.type = type;
handleObj.guid = handler.guid;
// Get the current list of functions bound to this event
var handlers = events[ type ],
special = jQuery.event.special[ type ] || {};
// Init the event handler queue
if (!handlers) {
handlers = events[ type ] = [];
// ... snip ...
}
// ... snip ...
// Add the function to the element's handler list
handlers.push(handleObj);
// Keep track of which events have been used, for global triggering
jQuery.event.global[ type ] = true;
}
// ... snip ...
}
En este punto me di cuenta de que la comprensión de que esto iba a tomar más de 30 minutos ... así que busqué Stackoverflow para
jquery get a list of all event handlers bound to an element
y encontró this answer para iterar sobre los acontecimientos ligados:
//log them to the console (firebug, ie8)
console.dir($('#someElementId').data('events'));
//or iterate them
jQuery.each($('#someElementId').data('events'), function(i, event){
jQuery.each(event, function(i, handler){
console.log(handler.toString());
});
});
Probando que en Firefox veo que el objeto events
en el atributo data
de cada elemento tiene un atributo [some_event_name]
(click
en nuestro caso) al que se le ha agregado una matriz de handler
objetos, cada uno de los cuales tiene un guid, un espacio de nombres, un tipo y un controlador. "Entonces", creo, "deberíamos teóricamente poder agregar objetos construidos de la misma manera al [element].data.events.[some_event_name].push([our_handler_object);
..."
Y luego voy a terminar de escribir mis hallazgos ... y encontrar un mucho mejor respuesta publicada por RusselUresti ... que me presenta algo nuevo que no sabía sobre jQuery (aunque lo estaba mirando directamente)
¿Cuál es la prueba de que Stackoverflow es la mejor pregunta- y el sitio de respuesta en Internet, al menos en mi humilde opinión.
Así que estoy publicando esto por el bien de la posteridad ... y marcándolo como una wiki comunitaria, ya que RussellUresti ya respondió la pregunta muy bien.
¿Está diciendo que cuando vincula el segundo controlador de eventos que desea invocar antes de la 1? –
¿Puedes dar un ejemplo cuando no es conveniente usar tu segundo ejemplo? – Russell
@jarret: Sí, exactamente – asgeo1