views:

280

answers:

3

I'm curious if its possible to create a custom event in jQuery that isn't bound to a DOM element.

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.

For example, this creates an event that is bound to a variable, not to a DOM element:

var myevent = new YAHOO.util.CustomEvent("mycustomevent");

All of the examples and documentation I have been reading for jQuery require something like:

$('body').bind('mycustomevent', function(){
    //do stuff
});
+6  A: 

You can trigger custom global events like this in 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.

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:

$(document).bind('mycustomevent', function (e, arg1, arg2, arg3) { /* ... */ });
Blixt
+1  A: 

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
});
Geuis
You should know that with `$()` you're still binding it to a DOM object (`$()` is the same as doing `$(document)`). `$({})` works, but you should know that it works because jQuery never checks whether it's a DOM object. It still wraps it with a jQuery object that has methods such as `append(...)` which will stop your script if called. Also, the behavior for wrapping non-DOM objects is undefined and may change in the future. So I still stand by my point in my answer, and recommend you to bind it to `$(document)` rather than a JavaScript object.
Blixt
+1  A: 

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.

$(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");
  });

});
bigmattyh
I think that's a bad idea. If you really want some element to attach events to, why not use `$('body')` or `$(document)`?
Blixt
It's just a convention that works. I prefer it over using document or body because it acts sort of like a sterile clearinghouse for events -- I know everything that's in it, and there's less likelihood of something bad unwanted happening by accident. Can you explain why you think it's a bad idea?
bigmattyh