views:

193

answers:

1

I have some HTML that looks like this:

<ul class="toggleList">
      <li><input type="checkbox" name="toggleCbx1" id="toggleCbx1" /><label for="toggleCbx1">Item 1</label></li>
</ul>

I'm using jquery to attach a click event to the LI that will then modify some classes and check or uncheck the checkbox within.

I attach the click event as such:

$("ul.toggleList li").click(function(){toggleStuff($(this));})

This works fine if I click anywhere in the LI. However, if I click on the LABEL within the LI, my click event is called twice.

Why is that? I think it's related to some sort of event bubling-up, correct?

As such, is the solution to use .triggerHandler? I've done some reading on it and looked at some examples but I don't quite understand the proper syntax for setting it up.

ADDENDUM:

Sam pointed out an option that I think leads to the solution. This maybe isn't a triggerHandler issue.

What appears to be happening is that (by default?) clicking on a LABEL will bubble-up a click event. The solution appears to be to check to see if the event was triggered by the label and, if so, over-ride that.

Doing some testing:

[...].click(function(evt){
  console.log(evt.target);
  if ($(evt.target).not("label")) {
   console.log("not label?");
   doMyThing($(this));
  }else{
   console.log("is label?");
  };

The above doesn't work. Whether I click on the LABEL or another element, it thinks it's not the label.

Oddly, reversing the logic does work:

[...].click(function(evt){
  console.log(evt.target);
  if ($(evt.target).is("label")) {
   console.log("is label?");
  }else{
   console.log("not label?");
   doMyThing($(this));
  };

Any idea what that is? I'll do more testing...

FINAL ADDENDUM:

Argh! User error. I, erroneously, assumed '.not' did the opposite of '.is'. Well, that's not true. .is does a comparison and returns a boolean. .not removes elements that matches (and therefore returns objects).

So, I guess one always has to check for .is and use an else when testing for 'not is'

+2  A: 

I can reproduce this. At least one of the duplicate event calls seems to be related to the use of the for attribute on the tag.

Regardless, if you check the source of the event (event.target) then it should ignore the unwanted event triggers you're receiving:

$("ul.toggleList li").click(function (evt) {
        if ($(evt.target).is("li")) {
            toggleStuff($(this));
        }
    }
);

See http://docs.jquery.com/Events/jQuery.Event#event.type for more info.

Sam C
Sam: Thanks. That's sending me down the right path. I can't check for 'is LI' though, as there are other elements within. So I'm trying to check for NOT label. However, jquery doesn't seem to recognize that. I'll append my original question with the new info.
DA