str*_*ger 5 javascript jquery events
我希望将目标origTarget上发生的所有事件路由/重定向到另一个对象otherObject.我想完成这样的事情:
/* Magic binding (doesn't work!). */
$(origTarget).bind('*', function(e) {
$(otherObject).trigger(e);
});
Run Code Online (Sandbox Code Playgroud)
这是否可以使用jQuery而不循环遍历每个可能的事件类型?
这个例子应该以'hello'警告:
var origTarget = { };
var otherObject = { };
/* Do magic binding here. */
$(otherObject).bind('alert', function() {
alert('hello');
});
$(origTarget).trigger('alert');
Run Code Online (Sandbox Code Playgroud)
我认为你所寻找的东西可以通过重新评估你如何约束你的事件来完成.如果您确实想要查看目标对象中发生的情况,则应将事件绑定到目标对象.
话虽如此,让我们试着找到一个解决方案
深入研究这些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);
Run Code Online (Sandbox Code Playgroud)
这通过读取someObject正在侦听的所有事件,然后在targetObject将调用所有事件处理程序的相同事件类型上绑定新事件来工作someObject.事件处理程序someObject可以如下所示:
$(someObject).bind('alert', function(e) {
if (e.proxyFrom) { alert('Proxied Succesfully!'); }
alert('test');
});
$(someObject).proxyEventsFrom(targetObject);
$(targetObject).trigger('alert');
Run Code Online (Sandbox Code Playgroud)
如果您将事件代理到代理的事件,则此方法可以轻松生成事件处理程序的递归循环.小心.
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);
}
})();
Run Code Online (Sandbox Code Playgroud)
如果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;
Run Code Online (Sandbox Code Playgroud)
这个解决方案是一条漫长的道路,内部所有jQuery事件都通过存储在其中的"句柄"函数传递$.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);
Run Code Online (Sandbox Code Playgroud)
它甚至可以与DOM Elements一起使用(尽管你需要传递元素,而不是jQuery对象)
jQuery.event.proxyEvents($('span')[0], $('input')[0]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2386 次 |
| 最近记录: |