Я думаю, что то, что вы ищете, может быть достигнуто путем переоценки того, как вы связываете свое событие в первую очередь. Если вы действительно хотите увидеть, что происходит в целевом объекте, вам следует привязать событие к целевому объекту.
Сказав это, давайте попробуем найти вам решение
Немного покопавшись в вещах jQuery.event
, я не вижу никакого "легкого" способа сделать это. Однако кажется, что события кэшируются в объекте с использованием jQuery.data(elem,'events')
. Есть несколько вариантов для изучения
Копирование связанных событий из одного объекта в другой
Решение для копирования потенциальных событий, написанное и протестированное в jQuery 1.3.2:
(function($){
$.fn.proxyEventsFrom = function(target) {
// cache this for later
var $target = $(target);
return this.each(function() {
// store a copy of the element to use in the event handler callback
var elem = this;
// get a list of events that I subscribe to
var events = $(this).data("events") || {};
$.each(events, function(type, handlers) {
// bind onto this event on the target
$target.bind(type, function(event) {
var evArgs = arguments;
// store the element that event originally fired on in the event object.
event.proxyFrom = this;
$.each(handlers, function(guid, handler) {
var ret = handler.apply(elem, evArgs);
// to behave like other event handlers.
if( ret !== undefined ){
event.result = ret;
if ( ret === false ) {
event.preventDefault();
event.stopPropagation();
return false; // stop our each loop too
}
}
}); // end $.each(handlers, function(guid, handler)
return event.result;
}); // end $target.bind(type, function(event)
});// end $.each(events, function(type, handlers)
});// end this.each(function() {});
}; // end $.fn.proxyEventsFrom
})(jQuery);
$(someObject).proxyEventsFrom(targetObject);
Это работает путем чтения всех событий, которые someObject
ожидает, и последующей привязки нового события к targetObject
того же типа события, которое вызовет все обработчики событий на someObject
. Обработчик события в someObject
может выглядеть так:
$(someObject).bind('alert', function(e) {
if (e.proxyFrom) { alert('Proxied Succesfully!'); }
alert('test');
});
$(someObject).proxyEventsFrom(targetObject);
$(targetObject).trigger('alert');
Этот подход может легко сгенерировать рекурсивный цикл обработчиков событий, если вы перенаправили события чему-то, что проксируется обратно. Будьте осторожны.
Переопределение jQuery.event.trigger
Можно переопределить функцию запуска событий, чтобы выполнить то, что вы хотите, хотя я предлагаю против этого по нескольким причинам: переопределять вещи в библиотеках опасно. и эта функция будет вызываться только для использования .trigger()
, очевидно - поэтому не применяется к стандартным событиям DOM.
(function() { // wrap this in a closure so origTrigger can't be overwritten.
var origTrigger = jQuery.event.trigger;
jQuery.event.trigger = function(event, data, elem, bubbling)
{
if (elem === origTarget) {
if (origTrigger.call(this, event, data, otherObject, bubbling) === false) return;
}
return origTrigger.apply(this,arguments);
}
})();
Сделать события цели === событиями другого объекта
Если у origTarget никогда не будет собственных событий, вы можете скопировать объект событий по ссылке.
// copy the events table by reference from otherObject "events" data
// (create if neccesary)
$.data(origTarget, 'events',
$.data(otherObject,'events') || $.data(otherObject,'events',{}));
// need to setup handler since jQuery isn't creating it for us
// function source found on line 2465 of jquery-1.3.2.js
var handle = $.data(origTarget, 'handle', function(){
return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
jQuery.event.handle.apply(arguments.callee.elem, arguments) :
undefined;
});
handle.elem = origTarget;
Пользовательская функция 'handle'
Это было долгий путь к этому решению, внутренне все события jQuery передаются через функцию handle, которая хранится в $.data(elem, 'handle')
. Поэтому, если вы переопределите эту функцию на своей цели, вы сможете передавать события другому объекту. Это решение предполагает, что у вас когда-либо есть только один дополнительный слушатель, однако его можно легко адаптировать, чтобы иметь более одного слушателя. Я думаю, что это лучший подход, который я придумала:
jQuery.event.proxyEvents = function(fromObject, toObject) {
// create an new handle function
var newHandle = function(event) {
// the test in the original handler returns undefined if jQuery.event.triggered
if (jQuery.event.triggered) return undefined;
// event should be safe - but just in case lets take a trick from
// jQuery.event.handle
event = arguments[0] = jQuery.event.fix(event || window.event);
// if we have a "listener"
if (arguments.callee.listener) {
// set proxyFrom for access in bound event handlers
event.proxyFrom = arguments.callee.elem;
// call the root "handle" function on the listener
jQuery.event.handle.apply(arguments.callee.listener, arguments);
// if we got a result of false from the event callbacks - exit early
if (event.result === false) return;
// clean that proxy property out
delete event.proxyFrom;
}
// this is all the basic 'handle' function does:
jQuery.event.handle.apply(arguments.callee.elem, arguments);
};
// properties of the handler function
newHandle.elem = fromObject;
newHandle.listener = toObject;
// store it
jQuery.data(fromObject, 'handle', newHandle);
};
jQuery.event.proxyEvents(origTarget, otherObject);
Он даже работает с DOM Elements (хотя вам нужно передать элемент, а не объект jQuery)
jQuery.event.proxyEvents($('span')[0], $('input')[0]);