Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the onclick element will trigger twice for label element

      window.onload = function(){           var wow = document.getElementById("wow");      	 wow.onclick = function(){      	     alert("hi");      	 }        }
    <label id="wow"><input type="checkbox" name="checkbox" value="value">Text</label>

This is my code, when I clicked on "Text" it will alert hi twice but when I clicked on the box, the onclick element will only trigger once, why?

like image 293
dramasea Avatar asked Jul 01 '14 02:07

dramasea


People also ask

Can we use Onclick in label in HTML?

Both radio and checkbox HTML type s can have an onclick call out to JavaScript.

Why Onclick works only once?

onclick event works only once in arctext script. Here is the code in Codepen: http://s.codepen.io/Noureddine/debug/JbbBQX. Well you only execute the random part once. If you want it to execute again, you need to move that logic inside.

Can a button do two things on click?

So the answer is - yes you can :) However, I'd recommend to use unobtrusive JavaScript.. mixing js with HTML is just nasty.

What elements can have an onclick?

All HTML elements can have an onclick attribute.


2 Answers

When you click on the label, it triggers the click handler, and you get an alert.

But clicking on a label also automatically sends a click event to the associated input element, so this is treated as a click on the checkbox. Then event bubbling causes that click event to be triggered on the containing element, which is the label, so your handler is run again.

If you change your HTML to this, you won't get the double alert:

<input id="wowcb" type="checkbox" name="checkbox" value="value"> <label id="wow" for="wowcb">Text</label> 

The label is now associated with the checkbox using the for attribute instead of wrapping around it.

DEMO

like image 176
Barmar Avatar answered Sep 23 '22 19:09

Barmar


If your intention is to respond only to clicks on the label and not on the checkbox, you can look at the event.target property. It references the element that called the listener so that if the click wasn't on that element, don't to the action:

window.onload = function(){   var el = document.getElementById('wow');   el.addEventListener('click', function(event) {      if (this === event.target) {       /* click was on label */       alert('click was on label');      } else {       /* click was on checkbox */       event.stopPropagation();       return false;     }    }, false); } 

If, on the other hand, you want to only respond to clicks on the checkbox (where a click on the label also produces a click on the checkbox), then do the reverse. Do nothing for clicks on the label and let ones from the checkbox through:

window.onload = function(){   var el = document.getElementById('foolabel');   el.addEventListener('click', function(event) {      if (this === event.target) {       /* click was on label */       event.stopPropagation();       return false;      } else {        /*       ** click is from checkbox, initiated by click on label       ** or checkbox                                         */        alert('click from checkbox');     }    }, false); } 

This version seems to have the most natural behaviour. However, changing the markup so that the label no longer wraps the checkbox will mean the listener is not called.

like image 37
RobG Avatar answered Sep 22 '22 19:09

RobG