简体   繁体   English

Javascript-循环使onclick事件发生而没有“ click”

[英]Javascript - loop is making onclick event happen without the “click”

So I have this piece of code: 所以我有这段代码:

window.onload = function () {make_buttons ('calc'); }

function make_buttons (id) {
    var input = document.createElement("input");
    input.type = 'text';
    input.id = 'inp';
    document.getElementById(id).appendChild(input);
    for (var i = 0;i < 10; i++){
        var btn = document.createElement ("button");
        btn.id = i;
        var txt = document.createTextNode (i);
        btn.appendChild(txt);
        var make_btn = document.getElementById(id).appendChild(btn);
        make_btn.onclick = document.getElementById("inp").value += i;
    }
};

So when I load the page, all the numbers from 1 to 9 are printed into my text field. 因此,当我加载页面时,所有从1到9的数字都会打印到我的文本字段中。 But adding a number in the text field should only happen when I click it because of the onclick thing. 但是由于onclick的缘故,只有在我单击它时才在文本字段中添加数字。

How can I overcome this issue? 我该如何克服这个问题?

You have a couple problems: 您有几个问题:

  1. You must assign a function reference to onclick not just a statement (using an event listener would be even better). 您必须为onclick分配一个函数引用,而不仅仅是一个语句(使用事件侦听器会更好)。
  2. Your loop variable will not be the proper value without wrapping it in a closure because your for loop has run to completion BEFORE the event handler is actually executed. 如果不将其包装在闭包中,则循环变量将不是正确的值,因为在实际执行事件处理程序之前,您的for循环已运行完毕。

You can change it to this: 您可以将其更改为:

function make_buttons (id) {
    var parent = document.getElementById(id);
    var input = document.createElement("input");
    input.type = 'text';
    input.id = 'inp';
    parent.appendChild(input);
    for (var i = 0;i < 10; i++){
        var btn = document.createElement ("button");
        btn.innerHTML = i;
        btn.id = i;
        parent.appendChild(btn);
        // wrap in a closure created by an 
        // IIEF (immediately invoked function expression) to capture 
        // the value of i uniquely for each event handler
        (function(index) {
            btn.onclick = function() {
                input.value += index;
            }
        })(i);
    }
};

See this reference for more info on the IIFE. 请参见本参考有关IIFE更多信息。

FYI, summary of fixes and simplifications: 仅供参考,修复和简化摘要:

  1. Fetches document.getElementById(id) just once and saves the result in a variable. 仅获取document.getElementById(id)一次,并将结果保存在变量中。
  2. Uses btn.innerHTML instead of creating a text node. 使用btn.innerHTML而不是创建文本节点。
  3. Uses btn instead of creating a new variable make_btn . 使用btn而不是创建新变量make_btn
  4. Uses the input variable in the event handler instead of finding it again. 在事件处理程序中使用input变量,而不是再次查找它。
  5. Creates the IIEF (immediately invoked function expression) to capture the value of i separately for each event handler so they don't all have the same value i has at the end of the for loop. 创建IIEF(立即调用的函数表达式)以分别捕获每个事件处理程序的i值,以便它们在for循环结束时不具有与i相同的值。
make_btn.addEventListener("click", (function(i){
    return function(){
        document.getElementById("inp").value += i;
    };
})(i));

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

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