Anders
Anders

Reputation: 499

jquery .on itself

I want an element to listen for a custom event that is actually triggered by itself. The custom event could possibly be triggered from a descendant but should then be ignored. It's important that it origins from itself. It also needs to be an event since I might need additional ancestors to listen for the events.

The .on (http://api.jquery.com/on/) method is able to provide this functionality. The selector argument can be used as filter. However this does not work to filter out the listener element itself.

In short:
-The event must be able to bubble
-The trigger and the listener is the same element
-The listener must ignore the custom event if it's triggered by an ancestors

How is this achieved?

Use case as requested

I use the jquery UI dialog widget

$el = $('#dialogDiv');
$el.on('customEvent', $el /* Won't work */, function() {
    //Do whatever
});
$el.dialog({
    open: function() {
        $el.trigger('customEvent');
    }
});

Upvotes: 2

Views: 307

Answers (3)

mekwall
mekwall

Reputation: 28984

Removing the part that doesn't work, will make it work.

$el = $('#dialogDiv');
$el.on('customEvent', function(e) {
    //Do whatever
});
$el.dialog({
    open: function() {
        $el.trigger('customEvent');
    }
});

However, you are asking for other features that a normal event might not support. You should look into setting up a jQuery special event. Check this awesome article by Ben Alman.

When it comes to your prerequisites:

  • An event is always able to bubble unless its propagation is hindered with event.stopPropagation() or event.stopImmediatePropagation()
  • The trigger and the listener is already on the same element
  • The listener will not know what triggered it unless you pass some an argument that can identify the element that triggered it and check if it's an ancestor

See test case on jsFiddle.

Upvotes: 1

pimvdb
pimvdb

Reputation: 154968

.on works fine; to ignore ancestors check e.target:

$el.on('customEvent', function(e) {
  if(e.target === this) {
    //Do whatever
  }
});

Upvotes: 1

Ja͢ck
Ja͢ck

Reputation: 173662

The selector that you can pass to .on() is used for the delegate target to match elements that can handle the click event (and it should be a string, not an object).

But in your case that's not necessary because your selector and the delegate target is the same thing, so this should work as expected:

$el.on('customEvent', function(evt) {
    //Do whatever
});

To detect if an event came from a descendent you would compare evt.target against the element itself.

Upvotes: 1

Related Questions