gpt4 book ai didi

循环内的Javascript addEventListener

转载 作者:行者123 更新时间:2023-11-29 10:51:11 26 4
gpt4 key购买 nike

我正在尝试向我在循环中生成的某些元素添加事件监听器。我必须使用 div.lastChild - 虽然在这个例子中它非常愚蠢。但这只是演示:

<div id="someArea">
</div>
<script type="text/javascript">
var func = function() {
alert('Callback works');
}

var func1 = function() {
alert('Test');
}

var func2 = function() {
alert('Test2');
}

var div = document.getElementById("someArea");
var callbacks = [func, func1, func2];
for(var i = 0; i <= 2; i++) {
div.innerHTML += '<input type="button" value="' + i + '" />';
(function(i) {
console.log(div.lastChild);
div.lastChild.addEventListener('click', callbacks[i], false);
}(i));

}
</script>

该事件仅适用于最后一个按钮。我在这里缺少什么?

最佳答案

为什么它不起作用。

当你这样做时......

div.innerHTML += '<input type="button" value="' + i + '" />';

...在循环的每次迭代中,您都在销毁 div 中的旧 DOM 节点(以及它们的处理程序),并重新创建新节点(但没有处理程序)。销毁包括在先前迭代中添加的 input 元素。

这就是只有最后一个有效的原因,因为在那之后,您已将处理程序分配给最后一个元素,但其他元素是全新的且未受影响。


一个解决方案。

与其将 DOM 视为一串 HTML 标记,不如考虑使用 DOM 方法来创建元素...

for(var i = 0; i <= 2; i++) {
var input = document.createElement('input');
input.type = 'button';
input.value = i;
input.addEventListener('click', callbacks[i], false);
div.appendChild(input);
}

请注意,我删除了立即调用的函数。对于您的代码,这是不必要的,因为 i 正在循环中而不是稍后在处理程序中进行评估。


DOM 不是 HTML,但 .innerHTML 让您认为它是。

了解 innerHTML 很重要。使用 DOM 时,没有 HTML 标记。因此,当您获取 .innerHTML 时,DOM 正在被分析,并创建了一个新的 HTML 字符串。

当您分配.innerHTML时,您将破坏所有当前内容,并用从 HTML 字符串创建的新节点替换它。

所以当你做...

div.innerHTML += '<input...>'

...您首先从当前内容创建新的 HTML 字符串,然后将新的 HTML 内容连接到 string,然后销毁旧节点并从新字符串创建新节点.

这是非常低效的,正如您已经看到的,它会破坏与原始元素相关联的所有数据,包括处理程序。


关于循环内的Javascript addEventListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951665/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com