jQuery 中未绑定到 DOM 元素的自定义事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1553342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom event in jQuery that isn't bound to a DOM element?
提问by Geuis
I'm curious if its possible to create a custom event in jQuery that isn't bound to a DOM element.
我很好奇是否可以在 jQuery 中创建一个未绑定到 DOM 元素的自定义事件。
I greatly prefer jQuery to YUI but there is one thing in YUI that I like, which is creating custom events and being able to subscribe to them later.
与 YUI 相比,我更喜欢 jQuery,但我喜欢 YUI 中的一件事,那就是创建自定义事件并能够在以后订阅它们。
For example, this creates an event that is bound to a variable, not to a DOM element:
例如,这会创建一个绑定到变量而不是 DOM 元素的事件:
var myevent = new YAHOO.util.CustomEvent("mycustomevent");
All of the examples and documentation I have been reading for jQuery require something like:
我一直在为 jQuery 阅读的所有示例和文档都需要如下内容:
$('body').bind('mycustomevent', function(){
//do stuff
});
采纳答案by Blixt
You can trigger custom global events like this in jQuery:
您可以在 jQuery 中触发这样的自定义全局事件:
jQuery.event.trigger('mycustomevent', [arg1, arg2, arg3]);
These will trigger for any element.
这些将针对任何元素触发。
Since jQuery is built around DOM objects, you have to bind your events to DOM objects. You can probably find some way to bind events without an element too (you did), but that's not a supported methodology.
由于 jQuery 是围绕 DOM 对象构建的,因此您必须将事件绑定到 DOM 对象。您也可以找到某种方法来绑定没有元素的事件(您确实做到了),但这不是一种受支持的方法。
As you wrote in your own answer, you can bind your event to a global DOM object if you don't want to bind it to an individual page element:
正如您在自己的答案中所写,如果您不想将事件绑定到单个页面元素,则可以将事件绑定到全局 DOM 对象:
$(document).bind('mycustomevent', function (e, arg1, arg2, arg3) { /* ... */ });
回答by sbichenko
According to a comment by John Resig, binding events to custom objects via jQuery is supported:
根据由John Resig的评论,结合事件通过jQuery自定义对象支持:
No particular reason why it's not documented (other than that it's rather non-traditional for most users) - but yes, we support it and have unit tests for it.
没有特别的原因为什么它没有被记录(除了它对大多数用户来说是非传统的) - 但是是的,我们支持它并对其进行单元测试。
So this works:
所以这有效:
var a = {foo: 'bar'};
$(a).on('baz', function() {console.log('hello')});
$(a).triggerHandler('baz');
>>> 'hello'
Most users will need triggerHandler()
, not trigger()
. If .trigger("eventName")
is used, it will look for a "eventName" property on the object and attempt to execute it after any attached jQuery handlers are executed (Source).
大多数用户将需要triggerHandler()
,而不是trigger()
。如果.trigger("eventName")
使用,它将在对象上查找“eventName”属性,并在任何附加的 jQuery 处理程序执行后尝试执行它(Source)。
EDIT (28.02.2017):
编辑(28.02.2017):
After using this pattern for about 2 years in a large codebase, I can attest that this is a bad idea. These custom events lead to incomprehensible data flows. Prefer callbacks instead.
在大型代码库中使用这种模式大约 2 年后,我可以证明这是一个坏主意。这些自定义事件导致难以理解的数据流。更喜欢回调。
回答by Geuis
For future readers, its fairly simple to do this. I did further research after posting my question. Unfortunately none of the other commenters were correct.
对于未来的读者来说,这样做相当简单。发布我的问题后,我做了进一步的研究。不幸的是,其他评论者都不是正确的。
In order to bind a custom event:
为了绑定自定义事件:
$().bind('mycustomevent', function(){
//code here
});
Also, you can build data into the event object that is later accessible:
此外,您可以将数据构建到稍后可访问的事件对象中:
$({mydata:'testdata'}).bind('mycustomevent',function(){
//code here
});
回答by TheBentArrow
Binding to non-dom elements has been removed in jQuery 1.4.4.
绑定到非 dom 元素已在 jQuery 1.4.4 中删除。
回答by Himanshu P
回答by Matt Howell
You can still arbitrarily trigger and respond to events using jQuery, even if you don't know what element to attach them to. Just create a "receiver" element in your document, to which you can bind all your custom events. This allows you to manage your event handling logic in one place, for all your non-element-specific events.
您仍然可以使用 jQuery 任意触发和响应事件,即使您不知道将它们附加到哪个元素。只需在您的文档中创建一个“接收器”元素,您就可以将所有自定义事件绑定到该元素。这允许您在一个地方管理所有非元素特定事件的事件处理逻辑。
$(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");
});
});
回答by Luca Reghellin
[EDIT]
[编辑]
Here's a working class that uses the concepts written below:
这是一个使用以下概念的工作班级:
https://github.com/stratboy/image-preloader
https://github.com/stratboy/image-preloader
It's just a sequential image preloader. You can subscribe to a bunch of events. Take a look.
它只是一个顺序图像预加载器。您可以订阅一堆事件。看一看。
[/EDIT]
[/编辑]
Old post:
旧帖子:
Here's another barebones example with callbacks like suggested by Himanshu P.
这是另一个带有回调的准系统示例,如 Himanshu P.
I'm building a class and I come from Mootools, where things like Classes and custom events directly implemented in classes (so not bound to DOM elements) are absolutely natural. So I tried a sort of workaround and share below.
我正在构建一个类,我来自 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);