Ok i have a lightbox which works quite well except for 1 issue. The images are dynamically built, it gets a list of say 10 images and loops through each displaying each image on a row. So i can see what is going wrong. No matter which image i select its showing the first image in the lightbox so i need to pass it a variable with the image path or image name.
I really dont have that much javascript experience but what im hoping to do is put the $popup_item->attributes()->name
into a variable, pass it via the onclick
event and then inside div
with id="light"
instead of passing $popup_item->attributes()->name
i pass the variable but not sure if that is the best approach or even where to start
There is a loop like this which loops through and prints out the popup container a bunch of times:
foreach($xml->config->popup as $popup_item){
}
and the html
<div id="popup_container">
<!-- We use a lightbox to show the image in full size since large popups are scaled -->
<a href = "javascript:void(0)" onclick = "document.getElementById('light').style.display='block';document.getElementById('fade').style.display='block'">
<!-- This is the scaled image -->
<!--popups are stored in images/popups/images/ in the following format -->
<!--id_popupname.png which we build dynamically below because -->
<!-- the popup name will always be same name as the popupimage with the user id preceeding it -->
<img src="images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>" alt="Popup Image"/>
</a>
<!--This holds the un-scaled image in the popup box which is hidden initially until you click the image-->
<div id="light" class="white_content">
<img src="images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>" alt="Popup Image"/></a>
<!--This allows you to close the lightbox window from within the lightbox window-->
<a href = "javascript:void(0)" onclick = "document.getElementById('light').style.display='none';document.getElementById('fade').style.display='none'">Close</a>
</div>
<div id="fade" class="black_overlay"></div>
</div> <!--end of popup container-->
And the lightbox css in case it helps:
.black_overlay{
display: none;
position: fixed;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=60);
}
.white_content {
display: none;
position: fixed;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
EDIT: Actually i would need to pass 2 variables, the $item_id
and the $popup_item->attributes()->name
but concept is the same
You're getting the same image every time because the DOM is selecting the first element it finds with the id of 'light'. ID's should be unique in HTML. Instead try this...
<div id="popup_container">
<a href = "javascript:void(0)" onclick = "document.getElementById('light_<?php echo $item_id ?>').style.display='block';document.getElementById('fade').style.display='block'">
<img src="images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>" alt="Popup Image"/>
</a>
<div id="light_<?php echo $item_id ?>" class="white_content">
<img src="images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>" alt="Popup Image"/></a>
<a href = "javascript:void(0)" onclick = "document.getElementById('light_<?php echo $item_id ?>').style.display='none';document.getElementById('fade').style.display='none'">Close</a>
</div>
</div>
Also, move the fade div outside of your loop. You only need one instance of it, not 10...
So if you were building this in raw PHP rather than using a templating engine it would look like...
echo '<div id="popup_container">';
foreach($xml->config->popup as $popup_item){
echo '<a href = "javascript:void(0)" onclick = "document.getElementById(\'light_'.$popup_item->attributes()->item_id.'\').style.display=\'block\';document.getElementById(\'fade\').style.display=\'block\'">
<img src="images/popups/images/'.$popup_item->attributes()->item_id."_".strtolower($popup_item->attributes()->name).'.png" alt="Popup Image"/>
</a>
<div id="light_'.$popup_item->attributes()->item_id.'" class="white_content">
<img src="images/popups/images/'.$popup_item->attributes()->item_id."_".strtolower($popup_item->attributes()->name).'.png" alt="Popup Image"/></a>
<a href = "javascript:void(0)" onclick = "document.getElementById(\'light_'.$popup_item->attributes()->item_id.'\').style.display=\'none\';document.getElementById(\'fade\').style.display=\'none\'">Close</a>
</div>';
}
echo '</div>';
echo '<div id="fade" class="black_overlay"></div>';
EDIT: I would look at a few of the other answers below. Some of them give a much better way of achieving this effect, however, my answer dealt with the question at hand, how to get the original code working.
You say that your loop prints out the popup container a bunch of times..
An issue with this approach is that you will end with duplicate id
on html elements..
This will cause the document.getElementById
to return only the first one that matches (as seems to be your problem)
You need to make your id
's unique (and the javascript that targets them)
You can use the ID of the div in CSS.
<style>
#dark {
display: none;
position: fixed;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=60);
}
#light {
display: none;
position: fixed;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
</style>
I have made a nice function here that will do the job.
<script>
function display_lightbox(path) {
var image = '<img src="' + path + '" alt="Large Image"/>';
document.getElementById('lightimg').innerHTML=image;
document.getElementById('light').style.display='block';
document.getElementById('dark').style.display='block';
}
</script>
The lightbox code with an extra container for the img tag generated by JavaScript.
<div id="light">
<div id="lightimg"></div>
<a href = "javascript:void(0)" onclick = "document.getElementById('light').style.display='none';document.getElementById('fade').style.display='none'">Close</a>
</div>
<div id="dark"></div>
Your thumb display code using the JavaScript function.
<div id="popup_container">
<a href="javascript:void(0)" onclick="display_lightbox('images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>');">
<img src="images/popups/images/<?php echo $item_id . "_" . strtolower($popup_item->attributes()->name) . ".png" ;?>" alt="Popup Image"/>
</a>
</div>
Or you can implement this little lightbox.
http://www.laptoptips.ca/javascripts/shutter-reloaded/
I know this is a late submission but I wanted to give it a try.
I modified many parts of this so it might not adjust to your css but it's more an exercise in reflection on javascript and the importance of clean code and separation
Some features
Some caveats
and now... ze code
<script>
(function () {
var
onDelegatedClick,
onLoad,
onUnload,
enlighten,
revert;
enlighten = function (node) {
var lightbox = document.getElementById('light');
// pass the clicked image source to our lightbox
lightbox.querySelector('img').src = node.querySelector('img').src;
// make it all visible
lightbox.style.display = 'block';
document.getElementById('fade').style.display = 'block';
};
revert = function () {
document.getElementById('light').style.display = 'none';
document.getElementById('fade').style.display = 'none';
};
onDelegatedClick = function (event) {
// find out where we need behaviour
var targetNode = event.target;
if (targetNode.tagName !== 'SPAN') {return;}
// clicked on the close button
if (targetNode.id) revert();
// clicked on any of the images, pass the <span>
else enlighten(targetNode);
};
onLoad = function () {
// add the delegator
document.getElementById('popup_container').addEventListener('click',onDelegatedClick,false);
};
onUnload = function () {
// dont forget to remove the listener
document.getElementById('popup_container').removeEventListener('click',onDelegatedClick,false);
};
window.addEventListener('load',onLoad,true);
window.addEventListener('unload',onUnload,true);
}());
</script>
<div id="popup_container">
<!-- foreach image -->
<!-- clicks have been delegated, no need for anchors, just delegate all clicks -->
<span class="lightBoxEnlightener">
<img src="images/popups/images/<?php echo $item_id."_".strtolower($popup_item->attributes()->name).".png" ;?>" alt="Popup Image"/>
</span>
<!-- end foreach -->
<!-- only one lightbox and darkbox required -->
<div id="light" class="white_content">
<!-- img src is empty, when the enlightening happens, it'll be populated from the clicked span -->
<img src="" alt="Popup Image"/>
<!-- clicks have been delegated -->
<span id="reverter">Close</span>
</div>
<div id="fade" class="black_overlay"></div>
</div>
the script
tag may be moved anywhere or to a separate file, the behaviour of the spans will become patent on document load
. I chose spans because having to deal with actual anchor
tags is sometimes cumbersome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With