Javascript for循环中HTML集合的事件侦听器和闭包

Javascript for循环中HTML集合的事件侦听器和闭包,javascript,for-loop,closures,htmlcollection,Javascript,For Loop,Closures,Htmlcollection,代码是 //Logic which works when the desired element is clicked function changeArtistPhotoAndBio(prop) { var artistPhoto = document.getElementsByClassName("artist-photo")[0]; var artistBio = document.getElementsByClassName("artist-bio")[0];

代码是

//Logic which works when the desired element is clicked
function changeArtistPhotoAndBio(prop) {
    var artistPhoto = document.getElementsByClassName("artist-photo")[0];
    var artistBio = document.getElementsByClassName("artist-bio")[0];

    var i = prop.getAttribute("src").indexOf(".jpg");
    var photoName = prop.getAttribute("src").slice (0, i);

    artistPhoto.style.background="url(" + photoName + "-large.jpg";
    console.log("it happened");
};

//Setting listeners for the click event in the loop
var artists = document.getElementsByClassName("gallery")[0].getElementsByTagName("img");
for (var i = 0; i < artists.length; i++) {
    artists[i].addEventListener("click", changeArtistPhotoAndBio(artists[i]));
}
并且click函数的事件处理程序不起作用。我尝试过在闭包中隔离处理程序,如下所示:

for (var i = 0; i < artists.length; i++) {(function(i) {
    artists[i].addEventListener("click", changeArtistPhotoAndBio(artists[i]));
}(i))
}
for(var i=0;i
但是输出仍然是一样的。因此有两个问题:

1) 为什么控制台输出包含七个处理程序调用的结果?如果我没有调用函数,只是将其设置为处理程序


2) 如何在HTML集合的“for”循环中设置处理程序

var artists = document.getElementsByClassName("gallery")[0].getElementsByTagName("img");
for (var i = 0; i < artists.length; i++) {
    artists[i].addEventListener("click", function(index) {
        return function() {
            //You can use index for the current clicked item index
            // console.log(index);
            var artistPhoto = document.getElementsByClassName("artist-photo")[0];
            var artistBio = document.getElementsByClassName("artist-bio")[0];

            var i = this.getAttribute("src").indexOf(".jpg");
            var photoName = this.getAttribute("src").slice (0, i);

            artistPhoto.style.background="url(" + photoName + "-large.jpg";
            console.log("it happened");

        }
    }(i));
}
var artists=document.getElementsByClassName(“画廊”)[0].getElementsByTagName(“img”);
for(var i=0;i

$('body*')
选择body中的所有元素。

它应该是例如
changeArtistPhotoAndBio.bind({},artists[i])
并且您缺少结束父项。这里是:
url(“+photoName+”-large.jpg”
感谢您的回答和注意括号。但是我已经尝试绑定函数,但没有效果(即处理程序不工作).当然,我试过你的例子,但仍然不起作用。你的意思是处理程序没有被触发?你应该提供复制你的问题的最低限度的示例,例如在JSFIDDLOk上,这里是小提琴:我已经通过它进行了测试,无论出于什么原因,当我查找“img”元素时,它都不起作用,但在查找“li”时确实起作用元素。因为使用了
artists[i]。添加了EventListener(“单击”,changeArtistPhotoAndBio(artists[i]);
您使用的返回函数
changeArtistPhotoAndBio
的处理程序结果,在您的情况下,该函数是
未定义的
(此函数不返回任何内容)。如果要将函数本身用作处理程序,则必须使用它的引用,或者可以将其包装在匿名函数中。基本上,使用
anyFunction()
调用函数
anyFunction
var artists = document.getElementsByClassName("gallery")[0].getElementsByTagName("img");
for (var i = 0; i < artists.length; i++) {
    artists[i].addEventListener("click", function(index) {
        return function() {
            //You can use index for the current clicked item index
            // console.log(index);
            var artistPhoto = document.getElementsByClassName("artist-photo")[0];
            var artistBio = document.getElementsByClassName("artist-bio")[0];

            var i = this.getAttribute("src").indexOf(".jpg");
            var photoName = this.getAttribute("src").slice (0, i);

            artistPhoto.style.background="url(" + photoName + "-large.jpg";
            console.log("it happened");

        }
    }(i));
}
$('body *').on('mouseover',function(){console.log(this.tagName)});