1

I want to allow to click on my buttons on conditions. So I use the .on() method to allow to click just when the class "clickable" is present. :

$(".button").on("click", ".clickable", function () { 
  alert("click");
});

$("#stop").click( function () {
  $(".button").removeClass('clickable');
});

But I can't click on my buttons from the beginning. Is my .on() method not correct ?

this my html structure :

<div class="button clickable">1</div>
<div class="button clickable">2</div> 
<div class="button clickable">3</div>

Thank you

Maxxx
  • 1,179
  • 3
  • 16
  • 21

3 Answers3

3
$(".button").on("click", ".clickable", function () { 
    alert("click");
});

The meaning of this is that clicking on any element with the class name of clickable which is WITHIN an element with a class of .button.

I think you want anything with both a class of button and clickable in which case it should be this:

$(".button.clickable").on("click", function () { 
    alert("click");
});
James Montagne
  • 77,516
  • 14
  • 110
  • 130
  • I'm not going to downvote you because you've got a reasonable suggestion, but the events will remain bound to the elements if the classes on the elements change. – zzzzBov Jan 27 '12 at 19:44
3

I am making the following assumption about the HTML structure:

<someelement class="button clickable"></someelement>

It sounds like you may be adding/removing elements to the page, or simply changing the selection of active buttons, you should use the delegate or live form of on using a parent node as the base selector. The simplest to use is document:

$(document).on('click', '.button.clickable', function () {...});

the selector in the second parameter has to be a descendant of the first selector (in this case, $(document)).


If you, instead, called:

$('.button.clickable').on('click', function () {...});

and then removed the clickable class (assume #foo is one of the buttons):

$('#foo').removeClass('clickable')

you'd still fire the event listener when you click on the button, because the event was bound directly on every element in the matched set.

Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • 2
    The simplest and most horrible option is to use document as the listener. There is almost always a better ancestor. zzzzBov has no way of knowing what that ancestor is (hence the 'document' suggestion) but I have no doubt you can find one. Still upvoting. – Greg Pettit Jan 27 '12 at 20:11
  • @GregPettit, it's the same as using `live` (which is deprecated in favor of this form) and is quite responsive. – zzzzBov Jan 27 '12 at 20:23
  • @zzzzBov - `.live()` is exactly why I argue that it's a bad choice. It's long been considered poor practice to use it; a better practice has been until now to use `.delegate()` with a proper listener. @Maxxx - at least use the `.on()` suggestion even if exactly as zzzzBov presents it.... unless you're stuck with something less than jQuery 1.7. He mentioned `.live()` because that's what his code reproduces... but it's a deprecated function! – Greg Pettit Jan 27 '12 at 21:01
0

If you want to allow click only when the button has class clickable then use this code. I am assuming our button has button class in it.

$(".button.clickable").on("click", function () { 
    alert("click");
});
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124