0

I have this situation whereby I have managed to remove the necessary class via jquery but when clicking on the same div with the removed class, it still behaves as if the class is not removed.

I have a test situation set up here: http://jsfiddle.net/4L9MK/

    <script>
    $(document).ready(function(){
    $('.next').click(function() {
    $(this).removeClass('next');
    alert('removed class');
    $(this).next().addClass('next');
    });

    });
    </script>
    </head>
    <body>

    <div style="width:500px;" class="siblings">
      <ul>ul (parent)  
        <li>li (sibling)</li>
        <li>li (sibling)</li>
        <li class="next">li (sibling with class name "next")</li>
        <li>li (the next sibling of li with class name "next")</li>
        <li>li (sibling)</li>
      </ul>   
    </div>

    </body>

Basically if you click the div called

 li (sibling with class name "next")

It gives alerts you saying the class 'next' was deleted, then it removes the class 'next' from the current div. However when you click the same div now without the class 'next', the alert still runs even though the class has been removed! Even weirder is that the sibling div which now has class 'next', when clicked, doesn't run the alert.

My question is, how do I ensure that the div with the removed class doesn't alert when clicked and the div with the new class does alert when clicked?

Thanks

user2028856
  • 3,063
  • 8
  • 44
  • 71

3 Answers3

2

You need to use event delegation

$('.siblings').on('click', '.next', function () {
    $(this).removeClass('next');
    alert('removed class');
    $(this).next().addClass('next');
})

Demo: Fiddle

Why? When you use the normal way of event handler registration the associated selector is evaluated only during the registration of event, then the handlers are attched to the target elements. After that if you change any properties associated with those elements it will not affect the already registered handlers.

In your case you need to evaluate the selector dynamically, that is where event delegation comes handy.

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
2

When you attach an event handler with something like $('.next').click, the event handler is attached to the particular set of DOM elements that have the class="next" at the time you call the code. If you later remove that class, it does not affect the event handlers in any way as they are already attached to the DOM elements.

If you want it to work the way you described, you can use delegated event handling instead where you attach the event handler to a parent object and you use .on() with a second selector and that selector is evaluated at the time of the event and will only call the event handler if the second selector is still true at the time of the event. Delegated event handling would look like this:

$("ul").on("click", ".next", function() {
    // your code here
});

You can read more about how delegated event handling works here:

Does jQuery.on() work for elements that are added after the event handler is created?

jQuery .on does not work but .live does

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Use event delegation method:

$(document).on('click','.next',function() {
$(this).removeClass('next');
alert('removed class');
$(this).next().addClass('next');
});

demo

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231