简体   繁体   中英

Why is the onclick only being assigned to the last object?

I am trying to assign an onclick function a certain type of item. So, within a for loop I have if(invType[i] != "empty") then within that if statement I have

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. 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

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. 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.

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.

  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. This can cause problems if you call other functions inside the loop that do the same thing, because they'll affect the outer loop.

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