Question

I'm using jQuery 1.10.2 in Wordpress 3.6.1.

I have an image map with 5 areas, each one having class "unclicked".

Each time I click on one of these areas I want to prevent the default behaviour when the href attribute is "#", increase a clicksNumber variable by 1 and remove the element's "unclicked" class in order to avoid increasing the clicksNumber variable after the first click.

I tried the following code but the variable keeps increasing even if, with the Inspect Element, I see that there aren't anymore areas with "unclicked" class.

jQuery('.unclicked').click(function (e) {
    nClicks = nClicks + 1;
    jQuery(this).removeClass('unclicked');
    e.preventDefault();
    alert("CLICK ON UNCLICKED ELEMENT, Elements Clicked" + nClicks);
});

Any ideas why this isn't working?

Was it helpful?

Solution

jQuery('.unclicked').on('click',function(e){
   nClicks = nClicks+1;
   jQuery(this).removeClass('unclicked');
   jQuery(this).off('click');
   e.preventDefault();
   alert("CLICK ON UNCLICKED ELEMENT, Elements Clicked" + nClicks);
});

Use .on() instead of .click(), then you can use .off() to unbind the handler.

The reason your problem was occurring is because even though you were removing the unclicked class, the elements themselves had event handlers bound to them that will stay bound regardless of changes to the elements structure.

Another way you could accomplish this without having to unbind each handler as you go, is delegate the event to the nearest static parent element.

jQuery('#parent').on('click', '.unclicked', function(e){
  // Your code
  // Remove .unclicked class
});

This would work because the handler gets evaluated when the event bubbles up to the #parent, which would check each time if the element matches the condition (which in the above case is that it has the class .unclicked)

OTHER TIPS

In addition to ahren's answer there are a few other (I think better) ways to do this.

jQuery provides the .one() function, which will result in an event handler being executed "at most once per element per event type", which saves you having to explicitly removing the event handler yourself. That would look like this:

jQuery('.unclicked').one('click', function(e) {
    // your code
});

However, it may be better to use event delegation instead:

jQuery(document).on('click', '.unclicked', function(e) {
    // your code
});

That will recognise a click on any .unclicked element in the document (so all of them); however, if you remove the unclicked class from it the event handler isn't going to be executed for it if you click it again. The advantage of this route is that if you wanted to reset things you'd only have to add the unclicked class back to the correct elements, you wouldn't have to rebind the event handlers as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top