My first jQuery plugin - An image gallery

Posted on Saturday, July 12th, 2008
Post image ('My first jQuery plugin - An image gallery')

This is my first jQuery plugin and to be honest I am quite proud of it. It’s nothing complicated - a simple image gallery/viewer. When calling the plugin you specify which images you want to use like this:

$('div.some-images img').gallery();

The script would take all images within "div.some-images" (or whatever you specified) and put them within the gallery.

You can see a DEMO of it here.

Other styles:

It’s fully unobtrusive, so you can still view the images when JS is disabled.

It can take three arguments: "speed" (generic speed for everything), "slideshow speed" (amount of time each image is shown during slideshow) and it can also take a third argument which I will explain later (Look below - “other tips”). I recommend having a speed of between 1000 and 2000:

$('div.some-images img').gallery(1000);

So, if you wanted to specify the amount of time paused on each image during a slideshow you would do it like this:

$('div.some-images img').gallery(1000,5000);
// So 5000 is the amount of time (milliseconds) each image is shown during a slideshow
// If you want to specify the slideshow speed but NOT the generic speed then do the following:
$('div.some-images img').gallery(null,5000); // 'null' induces the default speed

Most of the styling is handled in the CSS so the plugin has quite a lot of flexibility style-wise.

As you can see (in the DEMO) there is a description shown in the lower left hand corner of the image. This description can be specified by you in the longdesc attribute of the images. If an image does not have this attribute then the description box will not be shown for that particular image.

Originally, I put this script together for a project (and had not considered making it available as a plugin) so it’s not 100% customizable but I’ve tried my best. :)

A typical setup would be something like this (HTML):

<ul class="gallery">
	<li><img src="london.jpg" alt="Usual stuff happening in London" longdesc="A photo taken in London... blah blah blah" /></li>
	<li><img src="lens.jpg" alt="A Nikon Camera lens" longdesc="An emotive shot of a Nikon Lens... Yeh! ;)" /></li>
	<li><img src="goose.jpg" alt="A goose" longdesc="Just... a goose!" /></li>
	<li><img src="pagani.jpg" alt="Dream car - Pagani Zonda" longdesc="Not my photo, but still amazing! ... My dream car, the Pagani Zonda! ;)" /></li>
</ul>
With the above HTML you would call the script like this:
$('ul.gallery img').gallery(1000);

Downloads:

Other tips:

Earlier, I said that when calling the plugin you can specify styles within a third argument. I am using this in the DEMO to position the description box and the image menu:

$('ul.gallery img').gallery(null,null,
	function(){
		// * Some styles which need to be applied on every image-change:
		var imageOffset = $('#img-gallery img').offset();
		var bottomOfImage = $('#img-gallery img').height() - $('#img-description').height();
		$('#img-description').css({top: bottomOfImage});
		$('#img-gallery ul').css({right: -$('#img-gallery ul').width()});
	}
);

If you don’t want to specify the speeds in the first two arguments simply set them as “null” - this will set the speeds to the script’s default.

By default, the gallery will prepend itself within the body of the document. To change where the gallery puts itself within the DOM you’ll have to edit a line within the script. (line ~31)

For example, changing it to the following would make it append itself to the "mygallery" div:

$('div.mygallery').append(galleryStructure); // <- Line ~31

If you find any errors please let me know!

16 Responses to “My first jQuery plugin - An image gallery”

  1. Gravatar #1 :: Thomas Milburn Says:

    Well done for making a great plugin! With a few modifications, I might use this in my own projects.

    Can I suggest that you write a tutorial explaining how to make a jQuery plugin.

  2. Gravatar #2 :: Daniel Says:

    Wonderful, simply wonderful. Definitely a del.icio.us from me. You mast submit it to Noupe, so others could find and use your creation. I’ll look into this one, maybe I could add some more fancy stuff to it. But, yes, James, you are ought to be proud of it!

  3. Gravatar #3 :: henk Says:

    How can i make the slideshow start automaticly?

  4. Gravatar #4 :: Melissa Says:

    I am getting this message:
    The requested URL /imagegallery.html was not found on this server.

    Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

    Do you know what I am doing wrong? I have found it’s easier to look at the source of the demo site to copy and I did that on someone else’s sample for the Form instructions and that one worked. But this one I think I must be doing something wrong. I have copied your CSS, JS and HTML do I need a PHP and if I need a PHP what do I put in it?

  5. Gravatar #5 :: Melissa Says:

    I realized what the problem was I was having and I have fixed it but now I have the page up and 4 images but it’s just the images (4) in a column down and no buttons or anything. Suggestions?

  6. Gravatar #6 :: James Says:

    @Melissa- I’m glad you sorted out the problem! :)

    The reason that you can only see the images in a column and no buttons is either because you have JavaScript disabled or you’ve not downloaded the JavaScript dependencies correctly. The two needed files are jQuery and The plugin file. Make sure you have both of these in <script> tags at the top of your document in the <head>… And make sure you’re initiating the plugin at the bottom of your document:

    $('ul.gallery img').gallery(null,null,
    	function(){
    		// * Some styles which need to be applied on every image-change:
    		var imageOffset = $('#img-gallery img').offset();
    		var bottomOfImage = $('#img-gallery img').height() - $('#img-description').height();
    		$('#img-description').css({top: bottomOfImage});
    		$('#img-gallery ul').css({right: -$('#img-gallery ul').width()});
    	}
    );

    Please note it doesn’t have to be exactly as above.

  7. Gravatar #7 :: Melissa Says:

    Thank you so much! I got it to work.

  8. Gravatar #8 :: James Says:

    @Melissa great! :)

  9. Gravatar #9 :: X-Factor Blog Says:

    Hiya, love the plugin, thank you.
    However, is it possible to make the images clickable?
    I have tried adding

    <a></a>

    but no joy.

  10. Gravatar #10 :: Natalya Says:

    Good for people to know.

  11. Gravatar #11 :: JJ Says:

    X-Factor, I have adapted the code to allow the use of hyperlinks for your separate images. First of all you need to create a hyperlink inside the gallery class and inside the separate li tags as shown:

    <a href="URL" rel="nofollow"></a>

    Then you need to add a function caller for this new tag in the javascript on the page, as shown:

    $('ul.gallery a').getHyper();

    just above

    $('ul.gallery img').gallery( . . . )

    This completes the work on the html page.
    Next you need to add a handlling function for this a tag as shown:

    var hypes = [];
    jQuery.fn.getHyper = function() {	
        var hypers = this;
        $(hypers).each(function(i){
            hypes[i] = [this.href];
        })
    }

    this code will save the URL of each li tag into the hypes[] array. Make sure the hypes[] array is outside the function as it is used later.
    Next you need to add the a tag into the output string:

    var galleryStructure = '<a href="" rel="nofollow"></a>'+ssOption+'';

    make sure to add a class to this hyperlink so you can reference it later in the Start function.
    Next is to add URL to the hyperlink to the a tag with the class “img-hyp”:

    $('#img-gallery img').attr('src', img[n][0]).attr('alt', img[n][1]);
    $('#img-gallery a.img-hyp').attr('href', hypes[n]);
    var width = $('#img-gallery img').width();

    if you add in the middle line as shown here the code should work giving you the ability to add hyperlinks to each of your images.

  12. Gravatar #12 :: Omid Says:

    Hi,

    This is one of best jQuery plug-ins that I have ever seen .
    But I have one problem ! I tried to load your demo page with dial-up and ADSL connection , with both of them , first image of your gallery appears below of green frame but when I refresh page , the demo page loads correctly and I could see only green frame with 4 images inside it and there is not any image below of frame .
    Can I solve this problem !!?

    TNX

  13. Gravatar #13 :: Marc Says:

    Has anyone figured out how to autostart this gallery yet?

  14. Gravatar #14 :: Mike Says:

    Firebug says :

    $("ul.gallery img") is null
    $('ul.gallery img').gallery(null,null,
  15. Gravatar #15 :: sutra Says:

    Hi, nice gallery! I am testing it right now but it’s conflicting with Prototype Library. I’d already adding the noConflict, still it’s not working and worse, cripples my jquery accordion. In the plugin code, I see there are many “$”. Do I change them all to “jQuery”? Or is there a quicker way to fix this?

    Was comparing your plugin code with galleira, I see it has this at the very top:
    (function($){

    var $$;

    Thanks!

  16. Gravatar #16 :: JJ Says:

    In answer to henk and Marc, the following changes to the code will allow the javascript to play automatically on load.

    First of all you need to add a variable that will hold the currently active image. This is done previously using the “active” class in the hyperlink itsself. However if you try to use this then you will run into trouble. So I created the variable

    var gallery = this;
    var img = [];
    var currentImage = 0;
    . . .

    In the startSlideShow function at the bottom of the javascript file you need to change the code to the following

    function startSlideShow(){
         imgToLoad = currentImage;
         if (imgToLoad == gallery.length) {imgToLoad = 0;}
         window['galleryTimeout'] = setTimeout(function(){startSlideShow()}, slideShowSpeed)
         changeImage(imgToLoad, function(){eval(galleryTimeout);});
         currentImage++;
    }

    This will use the variable currentImage instead of using the active class to determine which is shown.

    Next you need to add into the changeImage function the new currentImage. So just add
    currentImage = n;

    The last step starts the animations automatically and makes sure that it doesnt play if there is only one image

    The code

    $('#img-gallery ul a#playstop').toggle(
    . . .
    )

    Needs to be replaced by

    $('#img-gallery ul a#playstop').toggle(
       function(){
          if(gallery.length &gt; 1){
             $(this).toggleClass('stop');
             stopSlideShow();
             return false;
          }else{
             $(this).toggleClass('stop');
             startSlideShow();
             return false;
          }
       },
       function(){
          if(gallery.length &gt; 1){
             $(this).toggleClass('stop');
             startSlideShow();
             return false;
          }else{
             $(this).toggleClass('stop');
             stopSlideShow();
             return false;	
          }
       }
    );
     
    if(gallery.length &gt; 1){
       $('#img-gallery ul a#playstop').toggleClass('stop');
       startSlideShow();
    }

    Now your page should automatically start playing provided there is more than one image.

Leave a Response

Allowed elements include: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <em> <i> <q cite=""> <strike> <strong>.
Please wrap any multi-line code snippets in the <pre> element. (Characters are automatically escaped this way) - also you can specify the language within the lang attribute, e.g. <pre lang="php">echo 'hello';</pre>. (Available languages: "php", "javascript", "html4strict")