# Optimize jQuery image gallery for production

I can't seem to find a very simple light weight image gallery, so I decided to build my own. I'm not an expert in jQuery/JavaScript, so I was hoping some suggestions could be made to make this production material. I have a working example on jsfiddle.

data-rel will end up being the full size image URL while img src will become the thumb url. I'd like to limit full size images from having to be all loaded at once on page render.

jsFiddle

<div id="gallery">
<img data-rel="http://2.bp.blogspot.com/-MUcNEVzLIB8/TrStjvP92kI/AAAAAAAABLI/eK3vb1QMrrw/s1600/slide1-new.png" src="http://2.bp.blogspot.com/-MUcNEVzLIB8/TrStjvP92kI/AAAAAAAABLI/eK3vb1QMrrw/s1600/slide1-new.png" style="max-width:150px;max-height:50px"/>

<img data-rel="http://1.bp.blogspot.com/-KDiH65CZ8Hs/TjO9rQbmt9I/AAAAAAAAAfg/HeVV38ckUzk/s1600/3.jpg" src="http://1.bp.blogspot.com/-KDiH65CZ8Hs/TjO9rQbmt9I/AAAAAAAAAfg/HeVV38ckUzk/s1600/3.jpg" style="max-width:150px;max-height:50px"/>

<img data-rel="http://4.bp.blogspot.com/-pZuNX8uqQhw/TjO9rDvyC8I/AAAAAAAAAfY/N91storzGWc/s1600/2.jpg" src="http://4.bp.blogspot.com/-pZuNX8uqQhw/TjO9rDvyC8I/AAAAAAAAAfY/N91storzGWc/s1600/2.jpg" style="max-width:150px;max-height:50px"/>

</div>

<div id="area">test</div>
<div id="button-previous">prev</div>
<div id="button-next">next</div>


JavaScript

$("#gallery img").first().load(function(){ activeImg($(this));
});

$("#gallery img").on('click, mouseover', function(){ activeImg($(this));
});

$('#button-next').click(function(){ var isLast =$('#gallery img.active').is(':last-child');

if (isLast) {
activeImg($('#gallery img').first()); } else { activeImg($('#gallery img.active').next());
}
});

$('#button-previous').click(function(){ var isFirst =$('#gallery img.active').is(':first-child');

if (isFirst) {
activeImg($('#gallery img').last()); } else { activeImg($('#gallery img.active').prev());
}
});

var activeImg = function($img) {$('.active').removeClass('active');

var imgUrl = $img.addClass('active').data('rel');$("#area").html("<img src='" + imgUrl + "' alt='description' />");
};


CSS

#button-previous {float:left;}
#button-next {float:right;}
img{border:1px solid #000}
img.active{border-color:red}

• Welcome to Code Review! Great question and kudos for providing a fiddle. +1! Oct 31, 2014 at 21:07

Why not make it a jQuery plugin?

A basic example to get you started:

(function ($, window, undefined) {$.fn.gallery = function() {

var $nextButton = this.find('div.button-next'),$previousButton = this.find('div.button-previous'),
$images = this.find('img');$images.on('click, mouseover', function(e){
activeImage($(e.target)); });$nextButton.on('click', function(){
var activeIndex = $images.filter('.active').index(), nextIndex = (activeIndex + 1 !==$images.length) ? activeIndex+1 : 0,
$nextImage =$images.eq(nextIndex);

activeImage($nextImage); }); function activeImage($img) {
$images.removeClass('active');$img.addClass('active');
};

return this;
};

})(jQuery, window);

$(function(){$('#gallery').gallery();
});


http://jsfiddle.net/4Lgtecx0/1/

I changed your id:s to classes in the code above so that you can have multiple galleries on the same page.

activeImage() will no longer pollute the global namespace.

Elements are cached instead of looked up over and over again (e.g. \$('#gallery') vs this).

Keep in mind that the load event doesn't work on cached images in IE. On the other hand, you don't need to listen for the load event - just apply the class to the first element as in my fiddle.

• Thanks Johan, What do you recommend doing with the main image? I see that was missing in your example. Shouldn't that be a part of the plugin as well so that we can utilize the click/mouse event handler? Also I see the preloaded image is missing, any recommendations? Nov 1, 2014 at 5:13
• I added those few missing pieces back in, just curious as to what your thoughts were. jsfiddle.net/4Lgtecx0/7 Nov 1, 2014 at 6:05
• I intentionally left some parts for you to figure out yourself ;) In short it looks good. Perhaps make a common function to handle next/prev. Keep your code DRY. Also, I'd make a fixed grid so that your images don't jump around depending on size. Something to consider when you're in the CSS. If you want your plugin more flexible, look in to passing some options to it, like this learn.jquery.com/plugins/basic-plugin-creation/… Nov 1, 2014 at 19:39
• Thanks Johan, in production I have a responsive design that also prevents jumping around as you'll see here, cardaddy.com/forsale/vehicle/… Anyhow, I'll work on further improvements, thank you again. Nov 3, 2014 at 2:04

It's quite fine, but it can be simplified a little bit. In the HTML, the img elements all have the same style value. It would be better to remove the style attribute from all the img, and define in the stylesheet instead:

#gallery img {
max-width:150px;
max-height:50px;
}

• Yes I agree and thanks, I probably should have done that for the demo, but I was a bit more focused on the js side. Nov 1, 2014 at 4:51