1

Sorry for my English, I'm not native English speaker.

I have problem with my code. I have on page something like this:

$('#hook label').on('click', function() {
    console.log('ok');
    icon = $(this).next('input').val();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="hook">
    <label><input> <img src="http://placehold.it/35x35" ></label>
    <label><input> <img src="http://placehold.it/35x35" ></label>
    <label><input> <img src="http://placehold.it/35x35" ></label>
    <label><input> <img src="http://placehold.it/35x35" ></label>
</div>

And this code is running twice if I click on image, but only one when I click on input or label element. How can I prevent to running this twice?

Here is example: http://jsfiddle.net/00akgoe7/2/

epascarello
  • 204,599
  • 20
  • 195
  • 236
Nolias
  • 101
  • 1
  • 10

4 Answers4

5

It's because of the default behavior of label. To stop that, you need to tell to the event object to stop is default behavior like this:

$('#hook label').on('click', function(ev) {
    ev.preventDefault();
    console.log('ok');
    icon = $(this).next('input').val();
});

Clicking on a label associeted with the for attribute or inside the label, focus the input with a "fake" click event. This is why you get the event twice since by extension, if you click the input, you click the label (the parent) also.

gaelgillard
  • 2,483
  • 1
  • 14
  • 20
  • Yes, this is correct. Here's a related question http://stackoverflow.com/questions/17185265/jquery-click-event-triggers-twice-when-clicked-on-html-label – krato Sep 17 '15 at 13:13
  • While this is the solution I think an explanation of how exactly this happens would be good too. Inputs inside labels receive `click` events from the label parent too. – Sergiu Paraschiv Sep 17 '15 at 13:13
  • @SergiuParaschiv apparently, label is in union with input but I would like to see some resource explaining this as well. – krato Sep 17 '15 at 13:16
  • I edit my response to be more precise about this behavior. Thanks for the proposition. – gaelgillard Sep 17 '15 at 13:19
  • This works, however it prevents the radio button from being selected – krato Sep 17 '15 at 13:23
  • Thanks! This works. @krato, solution for it is `if(ev.target.tagName.toLowerCase() == 'label' || ev.target.tagName.toLowerCase() == 'img') return;` – Nolias Sep 17 '15 at 13:43
1

It's two times because when you click on the label it send a click event also to the input and the new event bubbles back to the label. It's tricky :)

It's in all browsers for a better form usability.

So the another possible solution is:

$('label').click(function(e) {
    if (e.target.tagName === "LABEL") {
        alert("!! here")
    }
});

Try it live: http://jsfiddle.net/8qffhwm3/2/

Tomas Randus
  • 2,127
  • 4
  • 29
  • 38
0

You just need to add a preventDefault().

$('#hook label').on('click', function(e) {
    e.preventDefault();
    console.log('ok');
});

I expect that it help you.

-2

If you want prevent from the event being fired twice, you can use the 'mousedown' event handler. It will just be triggered once, as it is not triggered by standard by clicking the label.

Frederik Witte
  • 1,167
  • 2
  • 11
  • 35