Russell
Russell

Reputation: 17719

jQuery prevent other events after a click

I am trying to prevent multiple clicks on links and items, which is causing problems.

I am using jQuery to bind click events to buttons (jQuery UI) and image links (<a><img /></a>).

Is there a way to do-once-for-all prevent other events from firing after a click occurs?

Or do I have to maintain a global variable called _isProcessing and set it to true for each event handler?

Thanks

Edit: (clarification) Thanks for your answers, my problem isn't preventing the bubbling of the event, but preventing multiple concurrent clicks.

Upvotes: 30

Views: 83729

Answers (6)

hunter
hunter

Reputation: 63512

did you check out preventDefault?

$("a").click(function(e) {
    e.preventDefault();
}

you could also try stopImmediatePropagation() or stopPropagation()


You could also look into the one() event.

Attach a handler to an event for the elements. The handler is executed at most once per element.

Upvotes: 12

Arnold Zokas
Arnold Zokas

Reputation: 8560

Another way would be to use event.stopPropagation() and event.isPropagationStopped() for signalling:

Example:

$(button).click(function(e){
    if(e.isPropagationStopped())
        return; // propagation was stopped, so stop further execution

    // if you got this far - this event handler was called first
    // custom logic goes here

    // stop event propagation to signal other handlers
    e.stopPropagation();

    // if you need, call e.preventDefault() to prevent default behaviour
});

Repeat same logic for other event handlers.

Upvotes: 2

elo80ka
elo80ka

Reputation: 15805

You've got a couple of options:

  1. If your buttons/links will reload the page, you can simply unbind the click event handler:

    $('input:submit').click(fumction() {
        $(this).unbind('click');
        // Handle event here 
    })
    
  2. You can disable the buttons, and re-enable them once you're done (I think this should also work with <input type="image">):

    $('input:submit').click(function() {
        $(this).attr('disabled', 'disabled');
        // It also helps to let the user know what's going on:
        $(this).val('Processing...');
        // Handle event here 
        $(this).removeAttr('disabled');
    })
    

    I don't think this works on links though.

Upvotes: 2

user113716
user113716

Reputation: 322452

There are various ways to prevent concurrent clicks from running the code.

One way is to unbind('click') on the element, then .bind() it again when you're ready.

I'd rather use some sort of flag. It could be a variable, but I'd rather assign a class to the element, like .processing, and remove it when done. So you would have the handler check for the existence of that class to determine of the code should run.

$('someElement').click(function() {
    var $th = $(this);
    if($th.hasClass('processing'))
          return;
    $th.addClass('processing');
    // normal code to run
    // then when done remove the class
    $th.removeClass('processing');
});

Another option is to use the elements .data() to set a similar flag, like $(this).data('processing', true); Then set it to false when done.

Upvotes: 32

TehOne
TehOne

Reputation: 2659

There is event.preventDefault, event.stopPropagation and return false as already stated.

$("a").click(function(e) {
    e.preventDefault();
    e.stopPropagation();
    return false;
}

Upvotes: 26

Gintautas Miliauskas
Gintautas Miliauskas

Reputation: 7892

Return false from your event handlers, or call ev.stopPropagation() in every handler.

Upvotes: 4

Related Questions