循环中的JavaScript addEventListener
我正在努力通过Udacity的。其中一个实践项目是创建一个包含几张猫的照片的页面。每张照片都有自己的标题和计数器,指示每张照片被点击的次数。我一开始把所有内容都硬编码为html,但现在我试图通过JavaScript生成大部分页面,使其更通用、更易于更新。我已经能够让所有的文本和图像显示出来,我已经让第二个图像的计数器在点击时增加,但我不明白为什么第一个图像没有更新它的计数器。点击它甚至不会触发“点击”事件监听器 HTML:循环中的JavaScript addEventListener,javascript,Javascript,我正在努力通过Udacity的。其中一个实践项目是创建一个包含几张猫的照片的页面。每张照片都有自己的标题和计数器,指示每张照片被点击的次数。我一开始把所有内容都硬编码为html,但现在我试图通过JavaScript生成大部分页面,使其更通用、更易于更新。我已经能够让所有的文本和图像显示出来,我已经让第二个图像的计数器在点击时增加,但我不明白为什么第一个图像没有更新它的计数器。点击它甚至不会触发“点击”事件监听器 HTML: 有几件事 首先,您需要将i传递给函数: (function (i) {
有几件事 首先,您需要将
i
传递给函数:
(function (i) {
var currCat = cats[i];
...
}(i));
但第二点更棘手。您正在动态地创建元素,并试图将事件侦听器附加到这些元素,但这不起作用。您需要利用的是事件委派
——将事件侦听器附加到父元素,并捕获从附加元素冒出的事件
需要对代码进行一些更改才能使其正常工作
1) 向图像元素添加两个数据属性,以引用cat索引和cat名称:
<img data-name="' + currCat.name + '" data-index="' + i + '" + id="' + currCat.name + '-photo" src="' + currCat.photo + '">
3) 重写increaseCount
函数以说明这些更改
function increaseCount(index, span) {
cats[index].count++;
document.getElementById(span).innerHTML = cats[index].count;
}
在我看来,这应该是可行的,但实际上我还是有同样的行为。我知道问题出在哪里。请容忍我……:)我最终选择了一个不同的解决方案(请参阅更新的问题),但这很好,因为它仍然允许完全重写“cats”div,这将减少对现有代码的重写。谢谢。当您设置
.innerHTML
时,即使您要放回以前的内容,您也会丢失事件处理程序分配。事件处理程序分配与DOM节点本身关联,覆盖。innerHTML
将删除DOM的该部分并创建一个全新的子树。将其拆分为两个单独的循环:首先,构建内容,然后分配事件处理程序。或者通过附加DOM节点而不是通过.innerHTML
覆盖DOM来构建内容。我可以用您的建议Pointy解决这个问题。谢谢
(function (i) {
var currCat = cats[i];
...
}(i));
<img data-name="' + currCat.name + '" data-index="' + i + '" + id="' + currCat.name + '-photo" src="' + currCat.photo + '">
catDiv.addEventListener('click', function(e) {
if (e.target && e.target.nodeName == "IMG") {
var data = e.target.dataset;
increaseCount(data.index, data.name + '-count');
}
});
function increaseCount(index, span) {
cats[index].count++;
document.getElementById(span).innerHTML = cats[index].count;
}