ZuzEL
ZuzEL

Reputation: 13645

Intercept and prevent all click events if element has "disabled" class

I am really tired of this pattern:

$("#moveButton").click(function() {
    if ($(this).hasClass("disabled")) {
        return;
    }
    //do something
});

I want to intercept all click events for elements, that have class "disabled" dynamically added.

I tried this:

$('input,a,div').click(function(event){
    if ($(this).hasClass("disabled")) {
        event.preventDefault()
        event.stopPropagation();
    }
});

but somehow it is not working. This script is on the top of my page.js


UPDATE The pitfall is that 'disabled' class can be added dynamically.

So ones you have already added event listener to a button, there have to be a solution to INTERCEPT all its click handlers and check if this element is disabled now. Than if it is, stop this event to be catched by handlers.

Upvotes: 0

Views: 6609

Answers (4)

ZuzEL
ZuzEL

Reputation: 13645

SOLVED:

I have found two ways of interception:


1) Not an interception. Exactly as @adeneo said, we can use .on( with test method when attaching event handlers:

$(document).on('click', 'div:not(.disabled)', function() {
    alert('ok');
});

see his answer for more details and upvote his answer if you find this helpful.


2) We can put this code ON TOP for executing first, but make sure you add it when DOM is rendered:

$("a,div,input").click(function(event){
    if($(this).hasClass('disabled')){ 
       event.stopImmediatePropagation()
    }
});

And this will prevent all existing .click, .on('click', and .live('click' handlers from being executed. If they have no other parameters.

This solution is good if you already have tons of handlers and don't want to rewrite it. EXAMPLE

Upvotes: 1

adeneo
adeneo

Reputation: 318172

Just filter out those elements then ?

$('input,a,div').not('.disabled').on('click', function(){
    // do stuff 
});

if the class is added later, you can use a delegated event handler, and if you really want to return false for all elements that has that class or are within such an element:

$('input,a,div').on('click', function(e) {
    if ( $(e.target).closest('.disabled').length ) return false;
});

EDIT:

as noted above, you can filter out classes added later in the event handler, if the handler is delegated, like this example:

//bind an event handler to all DIV element that does NOT have a .disabled class

$(document).on('click', 'div:not(.disabled)', function() {
    alert('ok');
});

// even if we add the class later, the event handler above will filter it out

$('.test').eq(1).addClass('disabled');

EDIT

Upvotes: 2

Pieter
Pieter

Reputation: 1833

You can use the pseudo class :disabled:

$('input:disabled,a:disabled,div:disabled').click(function() {

    return false;

});

Upvotes: 0

Hushme
Hushme

Reputation: 3144

use this code

    $('input,a,div').click(function(event){
    if ($(this).hasClass("disabled")) {
        return false;
    }
});

Upvotes: 2

Related Questions