开发者

Avoiding the 'double event' when LABELS are clicked within an element with a click event

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 atta开发者_如何转开发ch 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'


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜