最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Lightbox issue when loading dynamic image name - Stack Overflow

programmeradmin5浏览0评论

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

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

Share Improve this question edited Nov 26, 2013 at 10:43 Gabriele Petrioli 196k34 gold badges271 silver badges328 bronze badges asked Nov 23, 2013 at 0:11 user1547410user1547410 8937 gold badges27 silver badges59 bronze badges 1
  • 1 you have an extra (not opened) </a> after the second img tag.. – Gabriele Petrioli Commented Nov 26, 2013 at 10:43
Add a ment  | 

4 Answers 4

Reset to default 6 +300

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

  • use of event delegation, one event handler for the entire popup container
  • separation of behaviour and content
  • easy maintenance, very descriptive code (it doesn't actually need any ments)

Some caveats

  • I changed things in the html, changes will be required in the css
  • If there are further changes in the html, the javascript will have to acodate to those changes
  • it doesn't take care of the second variable to pass (I don't understand what it is, if someone cares to explain...)
  • more but I forgot... sorry

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 bee patent on document load. I chose spans because having to deal with actual anchor tags is sometimes cumbersome.

发布评论

评论列表(0)

  1. 暂无评论