遍历localStorage生成的DOM元素绑定点击事件仅触发首个项是什么原因?
问题根源
- 事件监听器绑定位置错误:你将
addEventListener方法写在了forEach循环外部,整个绑定逻辑只会执行一次,仅会给循环最后一次迭代创建的<a>元素绑定点击事件,其余元素都没有绑定触发逻辑。 - 变量未声明作用域:循环内的
artistObj、artistList、artistName等变量都没有加let/const声明,默认挂载为全局变量,每次循环都会覆盖上一次的变量值,会引发意料之外的逻辑问题。 - 语法笔误:
object.keys的首字母需要大写,正确写法是Object.keys。
修复后的代码
// DOM获取逻辑提前到循环外,避免重复查询DOM损耗性能 const artistList = document.getElementById("displayResults"); Object.keys(localStorage).forEach((key) => { // 声明块级作用域变量,每次循环的变量互相独立不会被覆盖 const artistObj = JSON.parse(localStorage.getItem(key)); const artistName = document.createElement("a"); const artistResult = document.createElement("li"); artistName.innerHTML = artistObj[0].items[0].name; artistResult.appendChild(artistName); artistList.appendChild(artistResult); // 在循环内给当前创建的a元素绑定点击事件 artistName.addEventListener("click", getRelatedArtists); }); function getRelatedArtists(e) { console.log(e.target); }
可选优化(事件委托方案)
如果后续会动态增删艺术家列表,也可以用事件委托的方式,只给父元素绑定一次事件,减少内存占用:
const artistList = document.getElementById("displayResults"); // 父元素绑定事件,通过target判断点击的是否是目标a标签 artistList.addEventListener("click", (e) => { if(e.target.tagName === 'A') { console.log(e.target); // 直接在这里写对应的业务逻辑即可 } }) Object.keys(localStorage).forEach((key) => { const artistObj = JSON.parse(localStorage.getItem(key)); const artistName = document.createElement("a"); const artistResult = document.createElement("li"); artistName.innerHTML = artistObj[0].items[0].name; artistResult.appendChild(artistName); artistList.appendChild(artistResult); });
内容的提问来源于stack exchange,提问作者chris McGrath
相关产品推荐
相关产品推荐

