Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: live events and querying if an element will respond to an event

I would like to ask if an element will respond to a live event, without actually triggering that event.

HTML

<div id="foo">Click me!</div>

JS

$('#foo').live('mousedown', function() {
  console.log('triggered mousedown event');
}

if ($('#foo').__willRespondToLiveEvent__('mousedown')) {
  console.log('#foo is wired up properly');
}

This is a somewhat simple and contrived example, but I am looking for a replacement that actually works for __willRespondToLiveEvent__ psuedo code.

Is there anyway for jQuery to cough up this info without actually triggering the event?

like image 493
Alex Wayne Avatar asked Dec 22 '10 23:12

Alex Wayne


1 Answers

If you want a utility to which you could pass a selector, you could do this:

Example: http://jsfiddle.net/NMBsG/3/

$('#foo').live('click', function() {
    alert('hi');
});

(function($) {
    $.hasLive = function(sel, type) {
        var data = $.data(document);
        if (data && data.events && data.events[type]) {
            var evts = data.events[type];
            for (var i = 0, len = evts.length; i < len; i++) {
                if (evts[i].selector === sel) {
                    return true;
                }
            }
        }
        return false;
    };
})(jQuery);

alert($.hasLive('#foo', 'click'));

Or if you want to call it against a jQuery object, you could do this:

Example: http://jsfiddle.net/NMBsG/4/

$('#foo').live('click', function() {
    alert('hi');
});

(function($) {
    $.fn.hasLive = function(type) {
        var data = $.data(document);
        if (data && data.events && data.events[type]) {
            var evts = data.events[type];
            for (var i = 0, len = evts.length; i < len; i++) {
                if (evts[i].selector === this.selector) {
                    return true;
                }
            }
        }
        return false;
    };
})(jQuery);

alert($('#foo').hasLive('click'));

Note that both of these only check against the selector, since that is how .live() works. You could feasibly select the same element but using a different matching selector, and it would return false. As such, the selector needs to be an exact match.


EDIT:

Here's a modified version that uses .is() to test the jQuery object against the selectors that were given to .live() for the event type provided. As long as one element in the object matches a .live() handler for that event, it should return true.

Example: http://jsfiddle.net/NMBsG/5/

var test = $('#foo').live('click', function() {
    alert('hi');
});

(function($) {
    $.fn.hasLive = function(type) {
        var data = $.data(document);
        if (data && data.events && data.events[type]) {
            var evts = data.events[type];
            for (var i = 0, len = evts.length; i < len; i++) {
                if ( this.is(evts[i].selector) ) {
                    return true;
                }
            }
        }
        return false;
    };
})(jQuery);

alert($('#foo').hasLive('click'));

EDIT: Fixed crash when there are no .live() events assigned, thanks to @Gaby.

like image 113
user113716 Avatar answered Sep 27 '22 16:09

user113716