我很好奇是否可以在jQuery中创建一个未绑定到DOM元素的自定义事件。
我非常喜欢jQuery和YUI,但我喜欢YUI中的一件事,即创建自定义事件并能够在以后订阅它们。
例如,这会创建一个绑定到变量的事件,而不是DOM元素:
var myevent = new YAHOO.util.CustomEvent("mycustomevent");
我为jQuery阅读的所有示例和文档都需要:
$('body').bind('mycustomevent', function(){
//do stuff
});
答案 0 :(得分:43)
您可以在jQuery中触发这样的自定义全局事件:
jQuery.event.trigger('mycustomevent', [arg1, arg2, arg3]);
这些将触发任何元素。
由于jQuery是围绕DOM对象构建的,因此必须将事件绑定到DOM对象。你可以找到一些方法来绑定没有元素的事件(你做过),但这不是一种支持的方法。
正如您在自己的回答中所写,如果您不想将事件绑定到单个页面元素,则可以将事件绑定到全局DOM对象:
$(document).bind('mycustomevent', function (e, arg1, arg2, arg3) { /* ... */ });
答案 1 :(得分:39)
根据a comment by John Resig,支持通过jQuery绑定到自定义对象的事件:
没有特别的理由说明它没有记录(除了它对大多数用户来说相当不传统) - 但是,是的,我们支持它并对其进行单元测试。
这样可行:
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年后,我可以证明这是一个坏主意。这些自定义事件导致难以理解的数据流。更喜欢回调。
答案 2 :(得分:6)
对于未来的读者来说,这样做相当简单。在发布我的问题后我做了进一步的研究。不幸的是,没有其他评论者是正确的。
为了绑定自定义事件:
$().bind('mycustomevent', function(){
//code here
});
此外,您可以将数据构建到以后可访问的事件对象中:
$({mydata:'testdata'}).bind('mycustomevent',function(){
//code here
});
答案 3 :(得分:4)
在jQuery 1.4.4中删除了绑定到非dom元素。
答案 4 :(得分:3)
您仍然可以使用jQuery随意触发和响应事件,即使您不知道要将它们附加到哪个元素。只需在文档中创建一个“receiver”元素,您就可以绑定所有自定义事件。这使您可以在一个地方管理事件处理逻辑,用于所有非元素特定事件。
$(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");
});
});
答案 5 :(得分:3)
jQuery Callbacks提供了一种实现独立于DOM的pub-sub系统的简单方法。
链接页面底部附近是显示如何执行此操作的示例代码。
答案 6 :(得分:1)
[编辑]
这是一个使用下面概念的工作类:
https://github.com/stratboy/image-preloader
这只是一个顺序图像预加载器。您可以订阅一系列活动。看一看。
[/编辑]
旧帖子:
这是另一个带有Himanshu P.建议回调的准系统示例。
我正在构建一个类,我来自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);