Reputation: 502
I have several places throughout my code where I use .on
to attach events (usually to delegate the events). We're changing around how we're doing a few things, and we're now wanting to add a .disabled
class to the elements that we want to be disabled. I'd like to block all the events on disabled items without having to refactor each location, I'm wondering if it's possible.
Example code: I've added this to the top of my script
$('body').on('click', '.disabled', function(event){
console.log("blocked");
event.stopImmediatePropagation();
// event.preventDefault();
// event.stopPropogation();
return false;
});
And an example of my normal events:
$('.ActionsContainer').on('click', '.Link', functions.ClickAction);
Problem is that even with the return false and all the others it still runs both the "blocked" and functions.ClickAction
Is there anyway around refactoring every one? I mean I can change that line below to:
$('.ActionsContainer').on('click', '.Link:not(.disabled)', functions.ClickAction);
but that's really annoying, and feels brittle.
Upvotes: 1
Views: 132
Reputation: 4635
Assuming every .Link
has that container and you're handling all events at that container, this is the most straightforward way:
$('.disabled').click( function(e){ e.stopPropagation(); } );
stopProp prevents that event from ever bubbling up to the action containers.
Upvotes: 0
Reputation: 1204
It's not too hard. You'll need to take advantage of jQuery's special events and basically override calls to any of the original event handlers setup in the existing code. jQuery's special events hooks let you override a number of features of the event system. jQuery essentially sets up it's own handler on an element the first time a listener is attached, and then adds the callback for the listener to its queue. As other listeners get attached to the element later, their callbacks get added to this queue as well.
Using the 'events.special.click' hook, we can add a function that gets called prior to any callbacks on that element's event queue which lets us intercept the call and check for, as you mentioned, that the element has a 'disabled' class and if so, stop the original callback from executing; or if it doesn't have the class, allow the original callback to execute normally.
I've put together a jsFiddle to show how it works. See if that solves your issue. The code for the override using special events is embedded below the link:
http://jsfiddle.net/datchley/bthcv/
// ADDED TO OVERRIDE CLICKS ON 'DISABLED' ELEMENTS
(function($) {
$.event.special.click = {
add: function(handle) {
// Save original handler
var orig_handlefn = handle.handler,
$el = $(this);
// Reassign our new handler to intercept here
handle.handler = function(ev) {
if ($el.hasClass('disabled')) {
// Don't allow clicks on disabled elements
$('.output').html('<b>Warning</b> You clicked a disabled element!');
ev.preventDefault();
}
else {
return orig_handlefn.apply(this, arguments);
}
};
}
};
})(jQuery);
Upvotes: 2