9

Working with an input the following behaviour has been discovered. When the label is attached to the input with for attribute two click events will happen. Can someone please explain the behaviour of this "anomaly".

And if there a way to prevent the click happening on input if only the label was clicked, of course besides removing the for attribute.

document.addEventListener(`click`, onClick)

var counter = 0;

function onClick(event) {
  ++counter
  console.log(counter)
}
label {
  display: block;
  background-color: lightgrey;
  margin: 5px 0 5px;
}
<input id='input'>
<label for='input'>I belong to input</label>
<label>I belong to no one</label>
volna
  • 2,452
  • 4
  • 25
  • 61

4 Answers4

3

The first click is related to the label, the second to the associated input. As you can see, after clicking the label, the focus is set on the input. If you remove the input, the 2nd click won't be triggered. It's the normal behavior of the browser.

You can prevent this with event.preventDefault();.

document.addEventListener(`click`, onClick)

var counter = 0;

function onClick(event) {
  event.preventDefault();
  ++counter;
  console.log(counter);
}
label {
  display: block;
  background-color: lightgrey;
  margin: 5px 0 5px;
}
<input id='input'>
<label for='input'>I belong to input</label>
<label>I belong to no one</label>
Alexandre Annic
  • 9,942
  • 5
  • 36
  • 50
2

The label is a nested item, each item will trigger the event.

A simular question on how to prevent it, is already answered [here] (jQuery Click fires twice when clicking on label)

Laura Landuyt
  • 116
  • 1
  • 8
1

A click is processed for both elements.

document.addEventListener(`click`, onClick)

var counter = 0;

function onClick(event) {
  event.preventDefault();
  ++counter
  console.log(counter)
}
  • You assign processing of a click to the entire document, and processing will be performed on each element that you clicked on. The element label processes the click and send the click processing to its element from the attribute for. To prevent further processing of the current click, you must run the preventDefault event method. – Vladimir Proskurin Aug 21 '18 at 09:42
  • 1
    Spasibo vam ogromnoe! :) – volna Aug 21 '18 at 09:45
  • volna De nada :) – Vladimir Proskurin Aug 21 '18 at 09:57
1

You need to use event.preventDefault(); to prevent the click for the next item it will trigger click by default, which is input element in your case. But note that this will prevent click for all the elements in chain, which will eventually block the click chain which you may require for other elements.

document.addEventListener(`click`, onClick)

var counter = 0;

function onClick(event) {
  event.preventDefault();
  ++counter
  console.log(counter)
}
label {
  display: block;
  background-color: lightgrey;
  margin: 5px 0 5px;
}
<input id='input'>
<label for='input'>I belong to input</label>
<label>I belong to no one</label>
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62