Очень хороший вопрос ... Я был заинтригован, поэтому немного поработал; для тех, кто заинтересован, вот куда я пошел и что я придумал.
Глядя на исходный код для jQuery 1.4.2 Я видел этот блок между строками 2361 и 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;
};
});
Существует много интересные вещи здесь происходят, но часть мы заинтересованы в том, между линиями 2384 и 2388:
else {
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.add(this[i], type, handler, data);
}
}
Каждый раз, когда мы называем bind()
или one()
мы на самом деле делает вызов jQuery.event.add()
... так что давайте посмотрим на что (линии 1557 до 1672, если вы заинтересованы)
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 ...
}
В этот момент я понял, что понимание этого собирается занять более 30 минут ... так что я искал Stackoverflow для
jquery get a list of all event handlers bound to an element
и нашел this answer для Перебор связанных событий:
//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());
});
});
Тестирование того, что в Firefox я вижу, что объект events
в атрибуте data
каждого элемента имеет атрибут [some_event_name]
(click
в нашем случае), к которому прикреплен массив из handler
, каждый из которых имеет направляющую, пространство имен, тип и обработчик. «Итак, я думаю,« мы должны теоретически иметь возможность добавлять объекты, построенные таким же образом, к [element].data.events.[some_event_name].push([our_handler_object);
... »
И затем я иду, чтобы закончить запись своих выводов ... и найти лучший ответ, опубликованный RusselUresti ..., который вводит меня в нечто новое, что я не знал о jQuery (хотя я смотрел его прямо в лицо.)
Это доказательство того, что Stackoverflow - лучший вопрос, и-ответ на сайте в Интернете, по крайней мере, по моему скромному мнению.
Итак, я отправляю это ради потомства ... и отмечаю его как сообщество wiki, так как RussellUresti уже так хорошо ответил на вопрос.
Вы только что сказали, что когда вы связываете 2-й обработчик событий, вы хотите, чтобы он был вызван до 1-го? –
Можете ли вы привести пример, когда использовать второй пример не удобно? – Russell
@jarret: Да, точно – asgeo1