Javascript add事件在循环中使用闭包时无法正常工作

Javascript add事件在循环中使用闭包时无法正常工作,javascript,Javascript,我遇到的实际问题就像下面的测试代码一样 我需要将大量事件加法器打包到一个函数中,并多次调用它 它生成相同的结果,即事件不应用于每个元素 window.onload = function() { var body = document.body; var elText = '<input id="randId" type="text"/>'; var elTmp; var ids = []; var times = 3; var randId = functio

我遇到的实际问题就像下面的测试代码一样

我需要将大量事件加法器打包到一个函数中,并多次调用它

它生成相同的结果,即事件不应用于每个元素

window.onload = function() {
  var body = document.body;
  var elText = '<input id="randId" type="text"/>';
  var elTmp;
  var ids = [];
  var times = 3;
  var randId = function(){
    return Math.random().toString(36).substr(2,9);
  };
  var setEvent = function(el, text) {
    el.addEventListener('click', function(e) {
      el.value = text;
    });
  };
  for (var i = 0; i < times; i++) {
    ids.push(randId());
    body.innerHTML += elText.replace('randId', ids[ids.length - 1]);
    elTmp = document.getElementById(ids[ids.length - 1]);
    setEvent(elTmp, 'this is ' + (i+1));
  }
};
window.onload=function(){
var body=document.body;
var-elText='';
var-elTmp;
var-id=[];
var时间=3;
var randId=函数(){
返回Math.random().toString(36).substr(2,9);
};
var setEvent=函数(el,文本){
el.addEventListener('click',函数(e){
el.value=文本;
});
};
对于(变量i=0;i<次;i++){
id.push(randId());
body.innerHTML+=elText.replace('randId',ids[ids.length-1]);
elTmp=document.getElementById(id[id.length-1]);
setEvent(elTmp,'这是'+(i+1));
}
};
即使将这些代码包装在闭包中,事件也只应用于最后创建的元素,前两个元素不适用

参考这个

for(变量i=0;i
问题在于,每次迭代时,所有内部HTML都会发生变化。发生这种情况时,所有以前的事件侦听器都将被删除(因为元素已从DOM中删除)。我刚才回答了一个问题

根据:

.innerHTML
-删除元素的所有子元素,解析内容字符串并将结果节点指定为元素的子元素

要解决这个问题,可以使用插入元素。这样做时,不会触及/删除任何其他HTML,因为这只是插入HTML

for(变量i=0;i

当然,您也可以使用。

当您调用
innerHTML
时,body的内容一次又一次地被覆盖,事件侦听器一次又一次地被删除。
我认为您应该在
Jquery
中使用like
$('').append()
方法来添加
元素
,以获得解决方案。我只想解释一下为什么JS会删除您以前的事件处理程序,而您以前的html会被保留,因为您正在使用
+=
附加html。仔细看看这一点:

body.innerHTML += elText.replace('randId', ids[ids.length - 1]);
实际上,这是以下操作的快捷方式:

body.innerHTML = body.innerHTML + elText.replace('randId', ids[ids.length - 1]);
因此,首先,您得到的是
body.innerHTML
,它只是一个文本字符串,没有绑定到它的事件处理程序,您将用它添加新文本,然后将其设置为
body.innerHTML
。在此期间,它的工作方式如下所示:

.innerHTML
-删除元素的所有子元素,解析内容字符串并将结果节点指定为元素的子元素


基督你是我的英雄!
body.innerHTML += elText.replace('randId', ids[ids.length - 1]);
body.innerHTML = body.innerHTML + elText.replace('randId', ids[ids.length - 1]);