anyway i needed a simple image gallery for this small app and found the
following tutorial: jQuery mobile gallery which is nice and great to start with.
but the code is not that good... (js code) i didn't like things like:
code duplication, duplicate selectors, being just functions and not an object, and the fact that the selected image and first and last image is being handled by giving classes to elements on your screen. that is really bad in my book.
anyway i did a little re-factoring/changes and thought, why not share?
* note: blogger keeps adding values to the href of anchors with a hash tag. don't forget to remove them, and keep just the hash tag like: #imgshow
so this is what i did
the HTML looks like this:
the gallery itself
the dialog (should be placed outside you page content tag i have put it in the master layout)
just add this two to your view (html page) and you will be fine.
and a simple css (didn't change):
.gallery_content a img { height:80px; width:80px; padding:3px; background-color:#222; } #prevbtn, #nextbtn { margin:10px 15px; }
now for the interesting part... our JavaScript!
so lets break it down.
first part, initializing the gallery:
the old code looked like this:
$('.gallerycontent img').bind('tap',function(){ var src = $(this).attr("src"); var alt = $(this).attr("alt"); $('#dialogcontent').empty().append('' ); $('#dialoghead').empty().append('' ); $(this).parent().addClass('selectedimg'); }); ' + alt + '
The new re-factored init method will look like this:
var self = this; var allImages = null; var currentImage = null; function init() { allImages = self.getImages(); allImages.bind('tap',function(){ switchImages ($(this)); }); self.bindEvents(); } this.getImages = function () { return $('#galleryContent img'); }
Now 2 functions to show the next and previous images
function switchImages (imgToSwitch) { var src = imgToSwitch.attr("src"); var alt = imgToSwitch.attr("alt"); currentImage = imgToSwitch; // insert the image to the dialog's body $('#dialogcontent').empty().append('' ); // change the dialog header text $('#dialoghead h2').text(alt); } this.goNext = function () { // check if the current image is the last image if so get the first image // else just get the next image if (currentImage.is(allImages.last())) { var next = allImages.first(); } else { var next = currentImage.parent().next().find("img"); } switchImages(next); } this.goPrev = function () { // check if the current image is the first image if so get the last image // else just get the previous image if (currentImage.is(allImages.first())) var prev = allImages.last(); else var prev = currentImage.parent().prev().find("img"); switchImages(prev); }
the old next and prev functions from that tutorial were complete "copy paste" of the same code in the init function. instead of just extracting that logic to a function.
Finally handling the events for the gallery
old code from tutorial:
$('#nextbtn').bind('tap',function(event, ui){ gonext(); }); $('#imgshow').bind('swipeleft',function(event, ui){ gonext(); }); $('#prevbtn').bind('tap',function(event, ui){ goprev(); }); $('#imgshow').bind('swiperight',function(event, ui){ goprev(); });
New code: (no need for that empty anonymous functions)
this.bindEvents = function () { $('#nextbtn').bind('tap', self.goNext); $('#imgshow').bind('swipeleft', self.goNext); $('#prevbtn').bind('tap', self.goPrev); $('#imgshow').bind('swiperight', self.goPrev); }
So.. after all the code changes we now have an object not just a bunch of functions , we eliminated the code duplicates and the coupling of logic with UI (the first, last and current image was determined by giving a class to that element)
This is the complete JS code, just put it in you .js file and you can create an instance of it at document ready event.
var page = {}; $(document).bind("pageinit", function() { // creating a new instance of gallery page.gallery = new gallery(); }); function gallery () { var self = this; var allImages = null; var currentImage = null; function init() { // selecting all images just once. allImages = self.getImages(); // add the event for each image in our gallery allImages.bind('tap',function(){ var currImg = $(this); switchImages (currImg); }); self.bindEvents(); } this.getImages = function () { // selector for all gallery images return $('#galleryContent img'); } this.bindEvents = function () { // events for our gallery buttons $('#nextbtn').bind('tap', self.goNext); $('#imgshow').bind('swipeleft', self.goNext); $('#prevbtn').bind('tap', self.goPrev); $('#imgshow').bind('swiperight', self.goPrev); } function switchImages (imgToSwitch) { // just switching the old image the new one var src = imgToSwitch.attr("src"); var alt = imgToSwitch.attr("alt"); currentImage = imgToSwitch; $('#dialogcontent').empty().append('' ); $('#dialoghead h2').text(alt); } this.goNext = function () { // check if the current image is the last image if so get the first image // else just get the next image if (currentImage.is(allImages.last())) { var next = allImages.first(); } else { var next = currentImage.parent().next().find("img"); } switchImages(next); } this.goPrev = function () { // check if the current image is the first image if so get the last image // else just get the previous image if (currentImage.is(allImages.first())) var prev = allImages.last(); else var prev = currentImage.parent().prev().find("img"); switchImages(prev); } init(); }
this final JS code along with the short HTML and css will give you a pretty descent gallery for your jQuery mobile app.
enjoy!