javascript - 如何在 JavaScript 中动态创建事件和事件处理程序

标签 javascript html events dynamic handler

我正在尝试使用 for 循环使用唯一的监听器和处理程序动态创建按钮,但不幸的是我一定做错了什么,因为只有最后一个按钮有效。 更令人惊讶的是,当单击最后一个按钮而不是“Button No.3”时,它返回“Button No.4”

波纹管是代码,这里是一个jsfiddle http://jsfiddle.net/y69JC/4/

HTML:

<body>
    <div id="ui">
    some text ...
    </div>
</body>

Javascript:

var uiDiv = document.getElementById('ui');
uiDiv.innerHTML = uiDiv.innerHTML + '<br>';

var results = ["Button one","Button two","Button three","Button four"];

for(var n=0;n<results.length;n++)
{
 uiDiv.innerHTML = uiDiv.innerHTML + '<button id="connect'+n+'">option'+n+':'+results[n]+'</button><br>';
 var tempId = document.getElementById('connect'+n);
 tempId.addEventListener('click', function(){console.log("Button No."+n)}, false);
}

谢谢!

最佳答案

当您需要关闭时,这是一个经典案例:更改为:

var uiDiv = document.getElementById('ui');
uiDiv.innerHTML = uiDiv.innerHTML + '<br>';

var results = ["Button one", "Button two", "Button three", "Button four"];

for (var n = 0; n < results.length; n++) {
    // Note: do not use .innerHTML. Create new element programatically
    //       and then use .appendChild() to add it to the parent.
    var button = document.createElement('button');
    button.id = 'connect' + n;
    button.textContent = 'option' + n + ':' + results[n];

    uiDiv.appendChild(button);

    button.addEventListener('click', /* this is an inline function */ (function (n2) {
        // Here we'll use n2, which is equal to the current n value.
        // Value of n2 will not change for this block, because functions
        // in JS do create new scope.

        // Return the actual 'click' handler.
        return function () {
            console.log("Button No." + n2)
        };
    })(n)); // Invoke it immediately with the current n value
}

原因是 for 循环不会创建作用域,因此 "Button No. "+ n 始终使用 n< 进行计算 等于 results 数组中的元素数量。

需要做的是创建一个接受n作为参数的内联函数,并使用n的当前值立即调用它。然后,该函数将返回单击事件的实际处理程序。请参阅this回答一个很好又简单的例子。

编辑:您的代码正在使用 innerHTML 属性在循环中添加新按钮。它已被破坏,因为每次使用 uiDiv.innerHTML = ... 进行分配时,您都会删除此 div 中先前存在的所有内容并从头开始重新创建它们。这导致先前附加的所有事件处理程序被删除。从原理上讲,它看起来像这样:

uiDiv.innerHTML = ""

// First iteration of for-loop
uiDiv.innerHTML === <button1 onclick="...">

// Second iteration of for-loop
// 'onclick' handler from button1 disappeared
uiDiv.innerHTML === <button1> <button2 onclick="...">

// Third iteration of for-loop
// 'onclick' handler from button2 disappeared
uiDiv.innerHTML === <button1> <button2> <button3 onclick="...">

关于javascript - 如何在 JavaScript 中动态创建事件和事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18448284/

相关文章:

javascript - 关闭弹出窗口使其从 DOM 中消失并启用它

javascript - 如何使用 PHP 分割字符串?

css - div覆盖另一个div内容

c# - 隐藏扫描仪进度条窗口

php - php中事件的含义

javascript - 如何将谷歌地理定位的坐标传递给另一个函数?

javascript - 选择 radio 时,更改 vue.js version2 上的图像 src

javascript - 更改 angular-cli 中组件的默认文件夹

javascript - 根据事件状态显示参加按钮

javascript - jsPlumb 连接器显示错误路径