Submit your widget

jQuery Large Thumb Photo Gallery

Created 14 years ago   Views 14362   downloads 2867    Author jamesvec
jQuery Large Thumb Photo Gallery
View DemoDownload
109
Share |

What I decided to do was load the large images into the page with AJAX so that the initial load time was faster, and the gallery could handle more images on slower connections.

The HTML

Below is the new HTML markup for the thumb gallery. As before it is just a few unordered lists. The only differences are that #large_images which used to be a list is now a DIV, the urls for the large images have been added to the href attribute of the thumb link, and a new DIV called .loading has been added to contain our loading GIF.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Jquery Photogallery</title>
<link rel="stylesheet" type="text/css" href="css/style.css" media="screen" />
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script>
<script src="js/large_thumbs.js" type="text/javascript"></script>
</head>
<body>
<div id="wrapper">
  <div id="content">
    <div id="title"><img src="img/title.gif" width="283" height="45" alt="jquery photogallery" /></div>
    <div id="arrow_wrap">
      <div id="prev"><a href="[removed]void(0);"><img src="img/prev.png" alt="prev" /></a></div>
      <div id="photo_wrap">
        <div id="close_msg" class="hide">
          <p>Click Image To close</p>
        </div>
        <ul id="thumbs">
          <li>
            <ul class="group">
              <li>
                <div class="thumb_img"><a href="img/image1.jpg"><img src="img/thumbs/thumb1.jpg" alt="thumb1" /></a></div>
                <div class="thumb_desc">
                  <p>This texture came from an advertising board on the streets of New York.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image2.jpg"><img src="img/thumbs/thumb2.jpg" alt="thumb2" /></a></div>
                <div class="thumb_desc">
                  <p>This texture is from a wall I took a photo of.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image3.jpg"><img src="img/thumbs/thumb3.jpg" alt="thumb3" /></a></div>
                <div class="thumb_desc">
                  <p>This is some old wood with some interesting paint on it.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image4.jpg"><img src="img/thumbs/thumb4.jpg" alt="thumb4" /></a></div>
                <div class="thumb_desc">
                  <p>This is another old advertising board that had been picked apart</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image5.jpg"><img src="img/thumbs/thumb5.jpg" alt="thumb5" /></a></div>
                <div class="thumb_desc">
                  <p>I don't remember if I downloaded this one or shot it, but it is a garage door.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image6.jpg"><img src="img/thumbs/thumb6.jpg" alt="thumb1" /></a></div>
                <div class="thumb_desc">
                  <p>This is on an iron rail outside a brownstone that has been rusted.</p>
                </div>
              </li>
            </ul>
            <ul class="group">
              <li>
                <div class="thumb_img"><a href="img/image7.jpg"><img src="img/thumbs/thumb7.jpg" alt="thumb1" /></a></div>
                <div class="thumb_desc">
                  <p>Another concrete texture. Interesting colors.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image8.jpg"><img src="img/thumbs/thumb8.jpg" alt="thumb2" /></a></div>
                <div class="thumb_desc">
                  <p>Texture of rusted metal that I got off stockxchange.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image9.jpg"><img src="img/thumbs/thumb9.jpg" alt="thumb3" /></a></div>
                <div class="thumb_desc">
                  <p>Some weird "broccoli" according to my roomate, although I think it is suspect.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image10.jpg"><img src="img/thumbs/thumb10.jpg" alt="thumb4" /></a></div>
                <div class="thumb_desc">
                  <p>Some wood with graffiti on it and some kind of paper.</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image11.jpg"><img src="img/thumbs/thumb11.jpg" alt="thumb5" /></a></div>
                <div class="thumb_desc">
                  <p>Another rusty door for your pleasure</p>
                </div>
              </li>
              <li>
                <div class="thumb_img"><a href="img/image12.jpg"><img src="img/thumbs/thumb12.jpg" alt="thumb1" /></a></div>
                <div class="thumb_desc">
                  <p>This is the sidewalk on the north side of houston and mott I believe in NYC.</p>
                </div>
              </li>
            </ul>
          </li>
        </ul>
        <!-- end thumbs-->
        <div class="loading"><img src="img/ajax-loader.gif" /></div>
        <div id="large_images">

        </div>
        <!--end photo wrap -->

      </div>
      <div id="next"><a href="[removed]void(0);"><img src="img/next.png" alt="next" /></a></div>
      <!--end arrow wrap -->
    </div>
    <!-- end content-->
  </div>
</div>
<!-- end wrapper -->

</body>
</html>

We will use the href attribute to make the connection between the thumb and the large image with this new system, instead of using the rel attribute and the id of the large image.

The CSS

The CSS is also almost identical, except we have added attributes to the .loading class. As before I would copy my CSS and modify the styles to fit your design as some DIVS need to be absolutely and relatively positioned.

@charset "utf-8";
/* CSS Document */
/* v1.0 | 20080212 */

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {margin: 0;padding: 0;border: 0;outline: 0;font-size: 100%;vertical-align: baseline;background: transparent;}
body {line-height: 1;}
ol, ul {list-style: none;}
blockquote, q {quotes: none;}
blockquote:before, blockquote:after,
q:before, q:after {content: '';content: none;}
/* remember to define focus styles! */
:focus {outline: 0;}
/* remember to highlight inserts somehow! */
ins {text-decoration: none;}
del {text-decoration: line-through;}
/* tables still need 'cellspacing="0"' in the markup */
table {border-collapse: collapse;border-spacing: 0;}

p{color:#FFF; font-family:'Georgia', Times New Roman, Times, serif; font-style:italic; font-size:0.8em; line-height:1.5em;}
img{border:0;}
#title{width:283px; float:left; display:inline; margin:10px 0 10px 63px;}

#wrapper{width:1000px; margin:auto}
#content{width:1000px; float:left; display:inline;}
#arrow_wrap{width:1000px; float:left; display:inline;}
#photo_wrap{width:855px; height:478px; position:relative; float:left; display:inline; border:#464646 3px dashed; margin:5px; overflow:hidden;}
#thumbs{position:absolute; z-index:10; left:0; list-style-type:none;  display:inline;}
#thumbs li{ float:left; display:inline;}
#close_msg{background:#000; -moz-border-radius: 5px; -webkit-border-radius: 5px; border: 1px solid #000; padding: 10px; width:300px; text-align:center; position:absolute; z-index:14; top:45%; left:31%;}

#large_images{position:absolute; z-index:13;}
#large_images img{border:#464646 5px solid; width:845px; height:468px;}
#next{width:60px; float:left; display:inline;margin:5px 0;}
#prev{width:60px; float:left; display:inline;margin:5px 0;}
#prev a, #next a {display:none;}

.group{position:relative; float:left; display:inline; width:855px;}
.group li{margin:7px;}
.thumb_img{border:#ccc 1px solid;}
.group li, .thumb_img{float:left; display:inline; width:268px; float:left; position:relative;}
.group .hide{position:absolute; background:#000; padding:10px; bottom:0; left:0; width:248px; float:left;  z-index:11; margin:1px; }
.hide{display:none;}
.loading{display:none; position:absolute; top:40%; left:48%; z-index:15;}
.loading img{border:0 !important;}

The Main Difference, the Jquery

Instead of just hiding and showing images, we will now inject the image into a DIV in the DOM via AJAX. All the changes to this script for the most part are in the click function. Although we did remove 2 loops from the beginning of the script that are not needed anymore.

$(document).ready (function(){
//loops to add classes and identifiers
 $('.thumb_desc').each(function(index, element){$(element).attr("class", 'hide');});
    $(".group li a").each(function(index, element){$(element).attr("rel", 'image'+index);});

 //variables
 var mainImg = "";
 var showImg = "";
 var contWidth = $('#photo_wrap').width();
 var groups = $('.group').size();
 var totalWidth = groups*contWidth;
 var sectCount = 0;

 //slider if needed
  $('#thumbs').css('width',totalWidth);

  //if there are more than 6 items scroll
  if(groups>1){
   $('#next a').css('display','inline');
   }

   $('#prev a').click(function(){
                if(sectCount >0){
                    $('#thumbs').animate({left: '+='+contWidth+'px'},{duration: 'slow', easing: 'swing'})
                    sectCount=sectCount-1;
     //if there is no more sections to show hide arrow
                    if(sectCount==groups){
     $('#next a').css('display','none');
     }else{
     $('#next a').css('display','inline');
     }
     if (sectCount ==0) {
     $('#prev a').css('display','none');
     }else{
     $('#prev a').css('display','inline');
     }
                }

                })
            $('#next a').click (function(){
                if(sectCount<groups-1){
                $('#thumbs').animate({left: '-='+contWidth+'px'},{duration: 'slow', easing: 'swing'})
                sectCount = sectCount+1;
     //if there is no more sections to show hide arrow
       if(sectCount==groups-1){
     $('#next a').css('display','none');
     }else{
     $('#next a').css('display','inline');
     }
     if (sectCount ==0) {
     $('#prev a').css('display','none');
     }else{
     $('#prev a').css('display','inline');
     }
                }

                });

 // hover function SHOW ME DESCRIPTIONS MAN!
 $('.group li').hover (function(){ 

  $(this).children('.hide').slideToggle('fast');
 });

 

The first two loops which added the rel attribute and the id that matched it to 2 of our lists are gone, because we don’t need to make that connection anymore. Now the href attribute and a little AJAX will do the trick. Below is the new click function in all its glory, along with the new close function which had to be slightly tweaked to work with this new script.

$('.thumb_img a').click (function(){
 showImg = $(this).attr("href");
 $('.loading').fadeIn('slow', loadImage());
 return false;
 function loadImage(){
  var img = new Image;
  $(img).load(function () {
  $('.loading').fadeOut('slow', function(){
   $('#close_msg').fadeTo('slow', 0.5).delay(500).fadeOut('slow');
   });
  $('#large_images').append(this,showImgs());
  }).error(function () {
            // notify the user that the image could not be loaded
        }).attr('src', showImg).addClass('current');

 }
 function showImgs(){
  $('#large_images').fadeIn('slow');
   $('#prev a').fadeOut('slow');
   $('#next a').fadeOut('slow');
  }

 });

 //close image function
 $('#large_images').click (function(){
  $(this).fadeOut('slow', function(){
  $('.current').remove();
  });
  //see which arrows to display
   if(sectCount==groups-1){
     $('#next a').css('display','none');
     }else{
     $('#next a').css('display','inline');
     }
     if (sectCount ==0) {
     $('#prev a').css('display','none');
     }else{
     $('#prev a').css('display','inline');
     }

 });

});

Essentially on click we grab the href attribute of the clicked item, and save it to the variable showImg, then we fade in the loading GIF. After that we load the new image using the showImg variable we fade in the new image, fade out the loader and fade in the instructions for closing. Finally we add the class current to the large image so that we can easily target it with the close function.

The new close function fades out the image when clicked and then removes it from the DOM completely so that the DIV is ready for the next picture to be injected.