Javascript:addEventListener 无法在 for 循环中工作

标签 javascript arrays for-loop addeventlistener

情况:我从 API 获取 JSON 数组。 “div”来 self 代码中前面的 getElementByID。

问题:addEventListener 仅附加到列表中的最后一个元素。

    for(var i = 0; i < JSONarray.response.artists.length; i++){
      var artistName = JSONarray.response.artists[i];
      div.innerHTML += "<h4 id=\"artist" + i + "\" accessKey=\"" + artistName.id + "\">Artist Name: " +  artistName.name + "</h4>";
      document.getElementById("artist" + i).addEventListener("click", moreInfo, false);
    }

奇怪的事情:如果我将 addEventListener 放在它自己的 for 循环中(具有完全相同的循环脚本),它会非常高兴,并且我的所有列表项都会获得它们的监听器。

问题:我无法将所有内容放入一个 for 循环中是否有原因,或者这是我的代码?

注意:我正在使用 Chrome 来运行它,如果它恰好是浏览器的问题的话。

感谢您的宝贵时间!

最佳答案

您正在每次迭代 for 循环时修改 div 的innerHTML,从而导致绑定(bind)到以该 div 作为父节点的某个节点的所有事件处理程序丢失,因为修改innerHTML 会导致从 HTML 重新创建所有子节点。

考虑一下 div.innerHTML += foo; 实际上是 div.innerHTML = div.innerHTML + foo; 的简写,它应该很明显我的意思。

编辑:我意识到我的答案已被接受(截至 2013 年 4 月 8 日),但我仍然觉得我可以措辞更好一点。

node.innerHTML = bar 视为“将节点子节点的所有内容替换为可以从给定字符串(在 bar 中)解释的任何 HTML”。它恰好作为给定字符串的一部分发生,您通过 node.innerHTML 给出了节点前子节点的 HTML 序列化。所以您可能失去的不仅仅是事件处理程序!

如您所见,这不是添加 html 的最佳方式。

作为旁注,假设您确实必须向节点添加一堆子节点,如果事件可以冒泡(请参阅 HTML DOM: Which events do not bubble? ,或更完整的列表 Wikipedia's article on DOM events ) ,您还可以向节点添加事件处理程序,而不是向每个子节点添加处理程序,并且在现代浏览器(IE9+)中,可以按原样处理许多事件>冒泡。我最近还没有直接搞乱 DOM 中的事件冒泡,但许多第三方库很容易支持这种事件委托(delegate)。对于 jQuery,查看 jQuery.on,绑定(bind)声明的工作方式类似于:

 jQuery(parentnodeselector).on(eventname,childselector)

据我所知,自己处理事件冒泡并不是很难...您需要能够通过event.targetevent进行识别不过,如果事件通过正确的子级向上冒泡,则为 .target 的父级。

关于Javascript:addEventListener 无法在 for 循环中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15871591/

相关文章:

javascript - 如何使用 javascript 和 applescript 替换网页上的文本

javascript - 随机无右键单击消息不起作用

c# - 为什么本地数组的读/写速度比静态数组快?

javascript - 遍历对象字面量和数组

javascript - 在两个页面上共享 Javascript 变量

javascript - 如何在不使用ajax的情况下发送POST请求

.net - F#中的数组协方差

Java - 从具有两个给定索引的数组返回一个数组

javascript - 使用对象的属性从数组中查找和更改对象的一些更好的方法

java - Java中如何获取for循环的最后一个值?