Javascript事件监听器让我很困惑


Javascript event listener confuses me

我很困惑。我想构建一个画廊,你可以点击任何图像,并将全尺寸图像叠加在文档上(有点像facebook画廊)。

画廊的缩略图是用一些PHP显示的。它看起来像这样:

$i = 0;
while($img_dir = mysqli_fetch_assoc($gallery_q))
{
    $i++;
    echo
    '
        <div class="entry"><div class="image" id="' . $img_dir['dir'] . '">
<img id="img' . $i . '" src="' . $img_dir['thumb_dir'] . '" /></div></div>
    ';
}

然后,我用json_encode获取图像的数量,并通过循环生成一堆事件侦听器,如下所示:

for(var i = 1; i <= nbImg; i++)
{ 
    document.getElementById("img" + i).addEventListener("click", display(i));
}

显示功能如下:

function display(i)
{
document.getElementById("body").insertAdjacentHTML("afterBegin",
'<div id="display"><div><img src="' + document.getElementById("img" + i).parentNode.getAttribute("id") + '"></div>');
style.insertAdjacentHTML("beforeend",
"#display{z-index: 20; position: fixed; width: 1000px; height: 1000px; left: 50%; top: 10%; margin-left: -600px;");
}

好吧,它是有效的。。调用except display()时不考虑是否单击图像。但是,当我将此行为限制为仅一个图像时(即,事件侦听器不在循环中,也没有参数传递给函数;它只显示一个预设图像),则一切都很好。单击时会触发该事件。

事实上,这不是我第一次遇到侦听函数被触发的现象,无论我要求事件侦听器注意什么事件。这种情况最常发生在警觉的时候,我真的不明白为什么。有人能帮我吗?

不能这样分配函数。添加()会立即调用函数(要传递函数,请省略(),但您也将失去传递i的能力,event将被传递,因为它是传递给addEventListener的函数的第一个参数):

document.getElementById("img" + i).addEventListener("click", function() {
    display(i);
});

您可能会注意到i始终是最后一个迭代的循环var,所以您希望将其封装在一个闭包中:

for(var i = 1; i <= nbImg; i++) { 
    (function(i) {
        document.getElementById("img" + i).addEventListener("click", function() {
            display(i)
        });
    })(i);
}
调用display的原因与此代码有关。您调用的是display函数,而不是引用它。用闭包替换display函数。
for (var i = 1; i <= nbImg; i++) {
  document.getElementById("img" + i).addEventListener("click", function() {
    display(i)
  });
}