简体   繁体   中英

Strange onclick behavior for checkboxes. Trying to write onto browser console when a checkbox item is selected

Basically if I click on a checkbox, I want the name of the checkbox to be displayed on the console.

Here is the relevant javascript function and HTML.

javascript:

var list = [];

function test(){
      var checkBoxes = document.querySelectorAll('input[type=checkbox]')
    for(var i = 0; i < checkBoxes.length; i++) {
      checkBoxes[i].addEventListener('change',function(){
        if(this.checked){
          console.log(this.value)
          }
      });
  }
}

HTML:

<label><input type = "checkbox" onclick= "test()" name ="one" value ="one">test<br></label>
<label><input type = "checkbox" onclick= "test()" name ="two" value ="two" > test 1<br></label>
<label><input type = "checkbox" onclick= "test()" name ="three" value ="three" >test 2<br></label>
<label><input type = "checkbox" onclick= "test()" name ="four" value ="four" >test 3<br></label>
<label><input type = "checkbox" onclick= "test()" name ="five" value ="five" >test 4<br></label>
<label><input type = "checkbox" onclick= "test()" name ="six" value ="six" >Test 5<br></label>

If I click on the checkbox it is supposed to show in the console the name of the checked box.

However, something really strange happens and I don't understand why it is. I have a vague inkling as to why it's happening but it's not quite clear.

When I click on the first check box for example. I click on the checkbox named "one". The console displays:
one (as required)

But if I click on the next check box (for example I clicked on the checkbox named "four"). In the console it displays:
four
four

And the next checkbox clicked (if it's the one named "five") The console shows:
five
five
five

and so on....(incrementally repeating the checkbox name displayed on the console each time I click on another checkbox)

Why is it repeating ? When I click on the checkbox there should be technically one onclick event. How come it's counting all the other ones and repeating the console.log(this.value) bit?

Thanks in advance for any who may be able to give some idea as to why this is happening.

The problem is that you have inline click event handlers already set up and then when you click a checkbox, you programmatically set up a second one for the change event with .addEventListener() . So EVERY time you click a checkbox, you add yet another change event handler - - if a checkbox value gets changed, EACH AND EVERY handler associated with the change event will run. The more you click a checkbox, the more change events you set up.

Now, in order to change a checkbox, you need to click it. So, a future click will cause both the click and the change events to fire. Because of this way that change works with checkboxes and radio buttons, it's not usually used and instead click handlers typically do the job.

Inline event handlers should not be used, they are a 20+ year old technique that has many faults .

Also, you don't need to loop through the checkboxes in the handler. You'd use a loop to set up the handlers.

 // Get all the checkboxes into an Array var checkBoxes = Array.prototype.slice.call(document.querySelectorAll('input[type=checkbox]')); // Loop over the array only to set up event handlers on them checkBoxes.forEach(function(cb) { // Set up an event handler cb.addEventListener('change',function(){ // You don't need to loop again, just use the value of "this" if(this.checked){ console.log(this.value); } }); }); 
 <label><input type = "checkbox" name ="one" value ="one">test<br></label> <label><input type = "checkbox" name ="two" value ="two" > test 1<br></label> <label><input type = "checkbox" name ="three" value ="three" >test 2<br></label> <label><input type = "checkbox" name ="four" value ="four" >test 3<br></label> <label><input type = "checkbox" name ="five" value ="five" >test 4<br></label> <label><input type = "checkbox" name ="six" value ="six" >Test 5<br></label> 

The problem is that you keep adding event listeners to every checkbox whenever you click on one. This means that every time you click on a checkbox, more handlers are present that log to the console.

The sequence of events decoded:

  • Your page is loaded, nothing has been done so far.
  • Click on a check box => onclick is fired.
  • test() is invoked, an event listener for change is attached to each checkbox.
  • The onchange event fires and reaches the installed handler.
  • The event is logged to the console.
  • Click on another checkbox => onclick is fired.
  • test() is invoked, another event listener for change is attached to each checkbox.
  • The onchange event fires and reaches the first instance of the installed handler.
  • The event is logged to the console.
  • The onchange event reaches the second instance of the handler.
  • The event is logged to the console again.
  • and so on...

If you want to keep track of everything, I'd suggest the following JS to eliminate this problem (this doesn't need the onclick attribute at all):

document.addEventListener('DOMContentLoaded', function (p_event) {
var l_checkboxes = document.querySelectorAll('input[type="checkbox"]');
var l_item;

  for(l_item of l_checkboxes)
    {
    l_item.addEventListener('change', function (p_event) {
      if(p_event.target.checked)
        console.log(p_event.target.value);
      }, false);
    }
  }, false);

You are getting all the checkboxes on the page with document.querySelectorAll . Then you are looping through the list of all checkboxes in a for loop.

You can get the ID of the element clicked with

var checkBox = event.target.id;

then just display the name with console.log(document.getElementById(checkBox).value)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM