Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript event being overwritten in for loop

Tags:

javascript

I am creating JavaScript events on items within a loop, but every time I fire the event it only ever fires the last event created.

JavaScript:

var dirLinks = document.getElementsByClassName("dirLink"),
    iframe   = document.getElementById("tmpImg");

showDir.addEventListener('click', showDirContent, false);
showImgs.addEventListener('click', showImgsContent, false);

for (var i = 0; i < dirLinks.length; i++) {
    var link = dirLinks[i];
    link.onclick = function () {
        updateIframeSource(link.getAttribute("imgSrc"));
    }
}

function updateIframeSource(source) {
    iframe.src = source;
}

HTML:

<a class="dirLink" imgSrc="img1.jpg" href="#">img1.jpg</a><br />
<a class="dirLink" imgSrc="img2.jpg" href="#">img2.jpg</a><br />
<a class="dirLink" imgSrc="img3.jpg" href="#">img3.jpg</a><br />
<a class="dirLink" imgSrc="img4.jpg" href="#">img4.jpg</a><br />
<a class="dirLink" imgSrc="img5.jpg" href="#">img5.jpg</a>

<iframe id="tmpImg"></iframe>

No matter which link I click on, it will always hit the updateIframeSource function with img5.jpg passed in.

like image 825
ltoodee Avatar asked Jul 17 '26 00:07

ltoodee


2 Answers

It's because in javascript for loop don't create new scope in each iteration (only functions does) so you reference one variable link that in a function that is executed when loop is finished so it's always 5, to fix this just wrap the whole thing in anonymous function like this:

for(var i = 0; i < dirLinks.length; i++) {
    (function(link) {
        link.onclick = function () {
            updateIframeSource(link.getAttribute("imgSrc"));
        };
    })(dirLinks[i]);
}
like image 103
jcubic Avatar answered Jul 19 '26 13:07

jcubic


This is because the loop does not create a new scope. Because javascript has function scope:

var bindEvent = function(intId){
     var link = dirLinks[intId];
     link.onclick = function () {
            updateIframeSource(link.getAttribute("imgSrc"));
     }
}

for(var i = 0; i < dirLinks.length; i++) {
    bindEvent(i);
}

see jsfiddle

like image 41
Peter Rasmussen Avatar answered Jul 19 '26 14:07

Peter Rasmussen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!