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.
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]);
}
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
use also this
for(var i = 0; i < dirLinks.length; i++) {
var link = dirLinks[i];
link.addEventListener("click", updateIframeSource());
}
function updateIframeSource() {
return (function(event){
iframe.src = event.target.getAttribute("imgSrc");
alert(iframe.src);
});
}
The operation of assign an eventhandler are expensive it's better wrap all anchor links and use event delegation:
here how:
<div id="container">
<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>
</div>
<script>
var dirLinks = document.getElementsByClassName("dirLink");
var iframe = document.getElementById("tmpImg");
// Get the container
var container = document.getElementById("container");
//showDir.addEventListener('click', showDirContent, false);
//showImgs.addEventListener('click', showImgsContent, false);
container.addEventListener('click', function(evt){
// You can send the event or extract like this the value of "imgsrc"
updateIframeSource(evt.target.attributes.imgsrc.value);
});
function updateIframeSource(source) {
iframe.src = source;
}
</script>
Here is another way with forEach
loop
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>
JS:
var dirLinks = document.getElementsByClassName("dirLink");
var iframe = document.getElementById("tmpImg");
[].forEach.call(dirLinks, (l) => {
l.addEventListener('click', function() {
updateIframeSource(l.getAttribute("imgSrc"));
})
})
function updateIframeSource(source) {
iframe.src = source;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.