Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery: click function still works after removeClass()

Tags:

jquery

I'm trying to enable event listener on a class, but it doesn't work

DOM element:

<button class="btn btn-warning shopping"> Shop </button>

Here is Javascript event listener:
Once function is done it removes .shopping so event doesn't triggers anymore.

$('.shopping').click(function(e){
    var that = this;
    alert( $(that).attr('class')); //btn btn-warning shopping

    //Ajax request
    $.get('processShopping.php', function(data){
    if(data == "success"){
        if($(that).hasClass('shopping')){
            $(that).removeClass('shopping');
            alert( $(that).attr('class'));//btn btn-warning
        }
    }
    });
});

Shopping class has been removed, but action still triggers!

like image 645
gr3g Avatar asked Jan 23 '15 11:01

gr3g


2 Answers

For that you need to use event delegation,

$('body').on('click', '.shopping', function(e){

In the above code, i have used body for an example purpose, but you have to use a static closest element on that.

like image 66
Rajaprabhu Aravindasamy Avatar answered Oct 21 '22 05:10

Rajaprabhu Aravindasamy


Cause

First, to explain why you still get a code-response to the event, you need to understand that click() attaches an event listener to the element when that code runs. It does not matter how the element changes afterwards as the listener is connected to the element selected by $('.shopping') and not the selector $('.shopping') itself.

Solution

What you really needed was to created a delegated event handler. This will apply the selector at event time, not when the code is run.

You should connect a delegated event handler to a non-changing ancestor element. You should chose an ancestor that you know will always exist, but document is the best default if nothing else is closer to the desired elements.

$(document).on('click', '.shopping', function(e){

This will work as the filter is applied at event time. When the class is removed the click function will not get called.

Notes:

  • Never use body for delegated events as it has a bug relating to styling (basically a 0 calculated body height will stop mouse events bubbling to body).
  • Always use document as the default if nothing else is closer/convenient.
  • document has the added bonus that document always exists, and the event happens later, so you do not need to put the event registration code into a document ready handler!
like image 35
Gone Coding Avatar answered Oct 21 '22 06:10

Gone Coding