jQuery中未绑定到DOM元素的自定义事件?
我很好奇,如果它可能创build一个自定义事件的jQuery没有绑定到DOM元素。
我非常喜欢jQuery到YUI,但是YUI中有一个我喜欢的东西,那就是创build自定义事件,并能够稍后订阅它们。
例如,这会创build一个绑定到variables的事件,而不是DOM元素:
var myevent = new YAHOO.util.CustomEvent("mycustomevent");
我一直在阅读jQuery的所有示例和文档都需要如下所示:
$('body').bind('mycustomevent', function(){ //do stuff });
您可以在jQuery中触发像这样的自定义全局事件:
jQuery.event.trigger('mycustomevent', [arg1, arg2, arg3]);
这些将触发任何元素。
由于jQuery是围绕DOM对象构build的,所以您必须将您的事件绑定到DOM对象。 你也许可以find一些方法来绑定没有元素的事件(你做过),但是这不是一个支持的方法。
正如您在自己的答案中所写的那样,如果您不想将其绑定到单个页面元素,则可以将您的事件绑定到全局DOM对象:
$(document).bind('mycustomevent', function (e, arg1, arg2, arg3) { /* ... */ });
根据John Resig的评论, 支持通过jQuery绑定到自定义对象的事件:
没有什么特别的原因,为什么没有logging(除了对大多数用户而言这是非常传统的) – 但是,我们支持它,并进行unit testing。
所以这个工作:
var a = {foo: 'bar'}; $(a).on('baz', function() {console.log('hello')}); $(a).triggerHandler('baz'); >>> 'hello'
大多数用户需要triggerHandler()
,而不是trigger()
。 如果使用.trigger("eventName")
,它将在对象上查找“eventName”属性,并在执行任何附加的jQuery处理程序( Source )后尝试执行它。
编辑(28.02.2017):
在大型代码库中使用这种模式大约2年后,我可以certificate这是一个坏主意。 这些自定义事件导致难以理解的数据stream。 更喜欢callback。
对于未来的读者来说,这样做相当简单。 发布我的问题后,我做了进一步的研究。 不幸的是没有其他评论者是正确的。
为了绑定一个自定义事件:
$().bind('mycustomevent', function(){ //code here });
另外,您可以将数据构build到稍后可访问的事件对象中:
$({mydata:'testdata'}).bind('mycustomevent',function(){ //code here });
绑定到非DOM元素已被删除在jQuery 1.4.4。
你仍然可以使用jQuery任意地触发和响应事件,即使你不知道要附加到什么元素。 只需在文档中创build一个“接收者”元素,即可将所有自定义事件绑定到该元素。 这使您可以在一个位置pipe理事件处理逻辑,以处理所有非特定于元素的事件。
$(document).ready(function() { $(body).append('<div id="receiver">'); $("#receiver").bind("foo_event", function () { // decide what to do now that foo_event has been triggered. }); $("#some_element").click(function() { $("#receiver").trigger("foo_event"); }); });
jQuery callback提供了一种简单的方法来实现独立于DOM的pub-sub系统。
在链接页面的底部附近是示例代码,显示了如何做到这一点。
[编辑]
这是一个工作课,使用下面的概念:
https://github.com/stratboy/image-preloader
这只是一个顺序图像预加载器。 你可以订阅一大堆事件。 看一看。
[/编辑]
旧post:
这是另一个像Himanshu Pbuild议的callback的例子。
我正在构build一个类,我来自Mootools,在类中直接实现的类和自定义事件(因此不绑定到DOM元素)是绝对自然的。 所以我尝试了一种解决方法,并在下面分享。
var step_slider; //sandbox ;(function($) { //constructor var StepSlider = function(slider_mask_selector,options) { //this.onStep = $.Event('step'); this.options = null; this.onstep = $.Callbacks(); this.init(); }//end constructor StepSlider.prototype = { init:function(){ this.set_events(); },//end init set_events:function(){ if(this.options){ if(this.options.onstep){ this.subscribe('step',options.onstep); } } },//set_events subscribe:function(event,action){ this['on'+event].add(action); }, fire_onstep:function(){ this.onstep.fire({ data1:'ok' }); } }//end prototype/class //-------------------- $(document).ready(function() { step_slider = new StepSlider('selector'); //for example, say that you have a div#next-button, you can then do this: $('#next-button').click(function(){ step_slider.fire_onstep(); }); });//end domready })(jQuery);