Javascript - 在循环中动态分配 onclick 事件

IT技术 javascript html events button onclick
2021-02-15 18:12:57

我有一个非常简单的带有 js 代码的 html 页面:

<html>
    <head>
        <title></title>
    </head>
    <body>

        <div id="divButtons">

        </div>

        <script type="text/javascript">
            var arrOptions = new Array();

            for (var i = 0; i < 10; i++) {
                arrOptions[i] = "option" + i;
            }

            for (var i = 0; i < arrOptions.length; i++) {
                var btnShow = document.createElement("input");
                btnShow.setAttribute("type", "button");
                btnShow.value = "Show Me Option";
                var optionPar = arrOptions[i];
                btnShow.onclick = function() {
                    showParam(optionPar);
                }

                document.getElementById('divButtons').appendChild(btnShow);
            }

            function showParam(value) {
                alert(value);
            }        
        </script>
    </body>
</html>

该页面绑定了 10 个按钮,但是当您单击任何按钮时,它始终显示警报“option9”。怎么可能分配 onclick 事件来显示相应的选项!?

谢谢!

6个回答

你必须做这样的事情:

btnShow.onclick = (function(opt) {
    return function() {
       showParam(opt);
    };
})(arrOptions[i]);
更好的方法是使用节点的“data”属性,然后使用 this.data 作为函数的参数,这不会造成混淆。下面是一个例子: btnShow.data = arrOptions[i]; btnShow.onclick = function() { showParam(this.data); }
2021-04-19 18:12:57
这里究竟发生了什么?这对我也有用,但我也想了解:-)
2021-04-20 18:12:57
@MartinElvar 他创建了一个参数是 opt 的函数,然后当我们应用 (...)(arrOptions[i]) 然后它被传递给 opt 然后当我们点击 btnShow 然后这个函数被调用放。
2021-04-21 18:12:57

考虑这样一个事实,当 onclick() 函数被执行时,它只有:

showParam(optionPar);

,逐字逐句。optionPar 将在执行单击事件时解析,此时它很可能是您分配给它的最新值。您通常应该避免以这种方式传递变量。

您试图解决的问题最好通过重写以下内容来解决:

            btnShow.value = "Show Me Option";
            var optionPar = arrOptions[i];
            btnShow.optionPar = optionPar;
            btnShow.onclick = function(e) {
                // if I'm not mistaking on how to reference the source of the event.
                // and if it would work in all the browsers. But that's the idea.
                showParam(e.source.optionPar);
            }

接受的答案似乎有效,但似乎令人困惑,而且是一种有点麻烦的方法。更好的方法可能是对要为其分配事件侦听器的元素使用 data 属性。它很简单,易于理解,而且代码更少。下面是一个例子:

btnShow.data = arrOptions[i];

btnShow.onclick = function() {
  showParam(this.data);
}

我附上一个事件处理程序:

        window.onload = function() {
            var folderElement;
            tagFolders = document.getElementById("folders");
            for (i = 0; i < folders.length; i++) {
                folderElement = folderButtons[i];
                folderElement = document.createElement("button");
                folderElement.setAttribute("id", folders[i]);
                folderElement.setAttribute("type", "button");
                folderElement.innerHTML = folders[i];
                if (typeof window.addEventListener !== "undefined") {
                    folderElement.addEventListener("click", getFolderElement, false);
                } else {
                    folderElement.attachEvent("onclick", getFolderElement);
                }
                tagFolders.appendChild(folderElement);
            }

它可以从触发事件的元素中检索任何内容:

// This function is the event handler for the folder buttons.
function getFolderElement(event) {
    var eventElement = event.currentTarget;
    updateFolderContent(eventElement.id);
}

在这种情况下,您必须将选项嵌入到元素/标签中。在我的情况下,我使用 id。

对于 jquery,请查看API 中添加事件数据部分

...
for (var i = 0; i < arrOptions.length; i++) {

    $('<input id="btn" type="button" value="Show Me Option"><input>').appendTo("#divButtons")

    $('#btn').bind("click", {
        iCount: i},
    function(event) {
        showParam(arrOptions[iCount]);
    });
}