简体   繁体   English

为什么 onclick 只分配给最后一个对象?

[英]Why is the onclick only being assigned to the last object?

I am trying to assign an onclick function a certain type of item.我正在尝试为某种类型的项目分配 onclick 功能。 So, within a for loop I have if(invType[i] != "empty") then within that if statement I have所以,在 for 循环中我有if(invType[i] != "empty")然后在 if 语句中我有

if(invType[i] == "usable"){
    (function(num) {
       document.getElementById(num).onclick = function(){useItem(invName[num],num)};
    })(i);
}

only the last "usable" object is getting the onclick function.只有最后一个"usable"对象获得 onclick 函数。 Everyone keeps linking me to this question , but that doesn't help me.每个人都不断地将我与这个问题联系起来,但这对我没有帮助。 I have tried everything and I can't figure it out.我已经尝试了一切,但我无法弄清楚。 Can someone please give me a better explanation for what all that means and how I can get my code to work?有人可以给我一个更好的解释,说明这一切意味着什么以及如何让我的代码正常工作?

JSFiddle JSFiddle

Here's the whole code that adds all the buttons:这是添加所有按钮的完整代码:

function backpack(update) {
    i = 0;
    if (update != 1) {
        /*
                    tempA = document.getElementById("scene").innerHTML;
                    tempB = document.getElementById("textbox").innerHTML;
                    */
    }
    /*
                document.getElementById("textbox").innerHTML = '<br><br><input type="button" value="Close Backpack" onclick="closeBackpack()">';
                document.getElementById("scene").innerHTML = '<div id="backpack" style="height:400px; width:400px; background-image:url(files/sugame/sprites/backpackBackground.png); border-style:solid; border-width:8px; position:absolute; top:92px; left:192px"></div>';
                */
    for (i = 0; i < 9; i++) {
        if (invType[i] != "empty") {
            switch (i) {
                case 0:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:4px; top:4px;">';
                    break;
                case 1:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:136px; top:4px;">';
                    break;
                case 2:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:268px; top:4px;">';
                    break;
                case 3:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:4px; top:136px;">';
                    break;
                case 4:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:136px; top:136px;">';
                    break;
                case 5:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:268px; top:136px;">';
                    break;
                case 6:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:4px; top:268px;">';
                    break;
                case 7:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:136px; top:268px;">';
                    break;
                case 8:
                    document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:268px; top:268px;">';
                    break;
            }
            if (invType[i] == "usable") {
                (function (num) {
                    document.getElementById(num).onclick = function () {
                        useItem(invName[num], num)
                    };
                })(i);
            }
            if (invType[i] == "equipment") {
                document.getElementById(i).onclick = function (i) {
                    return function () {
                        equipItem(invName[i], i)
                    };
                }(i);
            }
        }
    }
}

The problem is with the way you're adding all the buttons to the DOM.问题在于您将所有按钮添加到 DOM 的方式。 You're doing:你正在做的:

document.getElementById("backpack").innerHTML += '<input type="button" value="' + invName[i] + '" id="' + i + '" style="position:absolute; left:4px; top:4px;">';

This re-parses the HTML of the entire DIV, so any event listeners on the old buttons are lost.这会重新解析整个 DIV 的 HTML,因此旧按钮上的任何事件侦听器都将丢失。

There are two simple ways to fix this:有两种简单的方法可以解决这个问题:

  1. Instead of concatenating HTML, use functions like createElement and appendChild to add to the DOM directly, without affecting previous elements.不是连接 HTML,而是使用createElementappendChild等函数直接添加到 DOM,而不会影响以前的元素。

  2. Use two loops: one loop adds all the buttons, the second loop adds the event listeners to them.使用两个循环:一个循环添加所有按钮,第二个循环向它们添加事件侦听器。

Another thing I noticed, but it's not related to the problem, is that you forget to declare i as a local variable in your functions.我注意到的另一件事,但它与问题无关,是您忘记在函数中将i声明为局部变量。 This can cause problems if you call other functions inside the loop that do the same thing, because they'll affect the outer loop.如果您在循环内调用其他执行相同操作的函数,这可能会导致问题,因为它们会影响外循环。

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

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