简体   繁体   English

复选框的奇怪的onclick行为。 选中复选框后尝试写入浏览器控制台

[英]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函数和HTML。

javascript: 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: 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. 当我单击复选框时,从技术上讲应该有一个onclick事件。 How come it's counting all the other ones and repeating the console.log(this.value) bit? 它如何计算所有其他值并重复console.log(this.value)位?

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() . 问题是您已经设置了内联click事件处理程序,然后单击复选框时,可以使用.addEventListener()以编程方式为change事件设置第二个事件处理程序。 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. 因此,每当您单击复选框时,都会添加另一个change事件处理程序--如果复选框值被更改,则与change事件关联的每个和每个处理程序都将运行。 The more you click a checkbox, the more change events you set up. 单击复选框的次数越多,设置的change事件就越多。

Now, in order to change a checkbox, you need to click it. 现在,为了change复选框,您需要click它。 So, a future click will cause both the click and the change events to fire. 因此,未来的click会同时触发clickchange事件。 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. 由于这种change可以与复选框和单选按钮一起使用,因此通常不使用它,而click处理程序通常可以完成工作。

Inline event handlers should not be used, they are a 20+ year old technique that has many faults . 不应使用内联事件处理程序,它们是20多年的老技术, 存在很多错误

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. 单击复选框=>触发onclick。
  • test() is invoked, an event listener for change is attached to each checkbox. 调用test()时,用于change的事件侦听器change附加到每个复选框。
  • The onchange event fires and reaches the installed handler. onchange事件将触发并到达已安装的处理程序。
  • The event is logged to the console. 该事件将记录到控制台。
  • Click on another checkbox => onclick is fired. 单击另一个复选框=>触发onclick。
  • test() is invoked, another event listener for change is attached to each checkbox. 调用test()时,将另一个用于change事件侦听器附加到每个复选框。
  • The onchange event fires and reaches the first instance of the installed handler. onchange事件将触发并到达已安装处理程序的第一个实例。
  • The event is logged to the console. 该事件将记录到控制台。
  • The onchange event reaches the second instance of the handler. onchange事件到达处理程序的第二个实例。
  • 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): 如果您想跟踪所有情况,建议使用以下JS来消除此问题(根本不需要onclick属性):

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 . 您将使用document.querySelectorAll获取页面上的所有复选框。 Then you are looping through the list of all checkboxes in a for loop. 然后,您将循环浏览for循环中所有复选框的列表。

You can get the ID of the element clicked with 您可以获取单击的元素的ID

var checkBox = event.target.id;

then just display the name with console.log(document.getElementById(checkBox).value) 然后只需使用console.log(document.getElementById(checkBox).value)显示名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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