I am a beginning javascript programmer. I am trying to create something similar to Lightbox 2, but much simpler. The only reason why I want to do it from scratch on my own is so that I can learn. However, I've been stuck on the last critical part where it displays the image. I believe the problem lies where I try to use onclick with assignment to an anonymous function:elem[i].onclick = function (){liteBoxFocus(imgSource,imgTitle); return false;}; . If you run my code and try clicking on the google logo it'll bring up the yahoo logo and title instead of google's logo and title. However when you click on the yahoo logo it works fine so it seems that the anonymous function only holds for the last loop. Thanks in advance!!!
I have placed the entire CSS/JS/XHTML in one page for your convenience.
<html> <head> <title>Erik's Script</title> <style type="text/css"> #liteBoxBg, #liteBox { display: none; } #liteBoxBg { background-color: #000000; height: 100%; width:100%; margin:0px; position: fixed; left:0px; top: 0px; filter:alpha(opacity=80); -moz-opacity:0.8; -khtml-opacity: 0.8; opacity: 0.8; z-index: 40; } #liteBox { background-color:#fff; padding: 10px; position:absolute; top:10%; border: 1px solid #ccc; width:auto; text-align:center; z-index: 50; } </style> <script type="text/javascript"> window.onload = start; function start(){ var imgTitle = "No title"; var imgSource; var elem = document.getElementsByTagName("a"); var i; //Dynamically insert the DIV's to produce effect var newDiv = document.createElement('div'); newDiv.setAttribute("id", "liteBox"); document.getElementsByTagName("body")[0].appendChild(newDiv); newDiv = document.createElement('div'); newDiv.setAttribute("id", "liteBoxBg"); document.getElementsByTagName("body")[0].appendChild(newDiv); //Check those anchors with rel=litebox for(i = 0;i < elem.length;i++){ if(elem[i].rel == "litebox"){ imgSource = elem[i].href.toString(); imgTitle = elem[i].title; elem[i].childNodes[0].style.border="0px solid #fff"; elem[i].onclick = function (){liteBoxFocus(imgSource,imgTitle); return false;}; } } //When foreground is clicked, close lite box document.getElementById("liteBoxBg").onclick = liteBoxClose; } //Brings up the image with focus function liteBoxFocus(source,title){ document.getElementById("liteBox").style.display = "block"; document.getElementById("liteBox").innerHTML = "<h1>" + title + "</h1>" + "<img src='" + source + "'/><br />" + "<a href='#' onclick='liteBoxClose();'><img src='images/litebox_close.gif' border='0' alt='close'/></a>"; document.getElementById("liteBoxBg").style.display = "block"; } //closes lite box function liteBoxClose(){ document.getElementById("liteBox").style.display = "none"; document.getElementById("liteBoxBg").style.display = "none"; return false; } </script> </head> <body> <a href="http://www.google.com/intl/en_ALL/images/logo.gif" rel="litebox" title="Google Logo"><img src="http://www.google.com/intl/en_ALL/images/logo.gif" alt="" /></a> <a href=" http://www.barbariangroup.com/assets/users/bruce/images/0000/4121/yahoo_logo.jpg" rel="litebox" title="Yahooo Logo"><img src=" http://www.barbariangroup.com/assets/users/bruce/images/0000/4121/yahoo_logo.jpg" alt="" /></a> </body> </html>
Your event handlers form a closure that remember a "live" pointer to the variables in the enclosing scope. So when they are actually executed, they have the last value imgSource
and imgTitle
had.
Instead, you can use this pattern to localize the variable values. This will create copies of source and title inside getClickHandler each time it is called. The returned function hence remembers the values in that iteration of the loop.
//Check those anchors with rel=litebox
for(i = 0;i < elem.length;i++){
if(elem[i].rel == "litebox"){
imgSource = elem[i].href.toString();
imgTitle = elem[i].title;
elem[i].childNodes[0].style.border="0px solid #fff";
elem[i].onclick = getClickHandler(imgSource, imgTitle);
}
}
//Brings up the image with focus
function getClickHandler(source,title){
return function() {
document.getElementById("liteBox").style.display = "block";
document.getElementById("liteBox").innerHTML = "<h1>" + title + "</h1>" +
"<img src='" + source + "'/><br />" +
"<a href='#' onclick='liteBoxClose();'><img src='images/litebox_close.gif' border='0' alt='close'/></a>";
document.getElementById("liteBoxBg").style.display = "block";
}
}