Skip to content

Instantly share code, notes, and snippets.

@mattsnider
Created December 14, 2012 18:55
Show Gist options
  • Save mattsnider/4287668 to your computer and use it in GitHub Desktop.
Save mattsnider/4287668 to your computer and use it in GitHub Desktop.
Improved Somewhat Simple Image Viewer
/**
* Copyright (c) 2007, Matt Snider, LLC. All rights reserved.
* Version: 1.2
*/
var Core = {Widget: {}};
/**
* The PhotoViewer class manages the slide show logic , requires a data object and a configuration object of DOM elements.
* @namespace Core.Widget
* @class PhotoViewer
* @dependencies core, object
* @param ds {Object} Required. The data JSON object.
* @param cfg {Object} Required. The DOM nodes to attach events to.
* @static
*/
Core.Widget.PhotoViewer = function(ds, cfg) {
// Constant variables
var $E = YAHOO.util.Event,
$ = YAHOO.util.Dom.get;
// Module variables
var config = YAHOO.lang.isObject(cfg) ? cfg : {},
isArray = YAHOO.lang.isArray(ds),
data = isArray ? {temp: ds} : ds,
F = function() {},
that = null, // this value will contain a global reference to 'this' Object
index = 0, // the current index in the desired Image set
aSet = []; // the current Image set
// Module dom namespace
var dom = {
// this node will be used to force certain browsers to pre-cache images
hnode: document.getElementsByTagName('body')[0].appendChild(document.createElement('div')),
cap: $(config.caption), // optional, ID attribute to the caption or title tag
img: $(config.image), // ID attribute to the 'img' tag
next: $(config.next), // ID attribute to the 'a' tag to show the next image
prev: $(config.prev) // ID attribute to the 'a' tag to showthe prev image
};
// ensure that the required values are present
if (! dom.img) {alert('PhotoViewer - Main image is missing in DOM, an <IMG> tag with ID: ' + config.image + ' is required.'); return;}
if (! dom.next) {alert('PhotoViewer - Next anchor is missing in DOM: an <A> tag with ID: ' + config.next + ' is required.'); return;}
if (! dom.prev) {alert('PhotoViewer - Previous anchor is missing in DOM: an <A> tag with ID: ' + config.prev + ' is required.'); return;}
// make hnode invisible
dom.hnode.style.overflow = 'hidden';
dom.hnode.style.height = '0px';
// Module event namespace
var evt = {
/**
* Callback function for changing a set; the ID of the trigger element is used to determine the set
* @method onChange
* @param e {Event} Required. The triggered JavaScript Event; onclick.
* @private
*/
onChange: function(e) {
$E.stopEvent(e); // stops the anchor tag from executing its normal behavior; this way only this action occurs
that.changeSet($E.getTarget(e).id); // changes the active set to the image group identified by the Attribute ID of triggering anchor tag
},
/**
* Callback function for click next; increases the index by 1; when the index exceeds the greatest position in the set (set.length-1), the index is set to the first position in the set (0).
* @method onNext
* @param e {Event} Required. The triggered JavaScript Event; onclick.
* @private
*/
onNext: function(e) {
$E.stopEvent(e); // stops the anchor tag from executing its normal behavior; this way only this action occurs
index++; // increase the index of set by one
if (index === aSet.length) {index = 0;} // if exceeding the maximum length of the set, index should wrap to the first value
that.changeImage(); // call global Function to actually change the image
},
/**
* Callback function for click previous; reduces the index by 1; when index is less than the smallest position in the set (0), the index is set to the last value in the set (set.length-1).
* @method onNext
* @param e {Event} Required. The triggered JavaScript Event; onclick.
* @private
*/
onPrev: function(e) {
$E.stopEvent(e); // stops the anchor tag from executing its normal behavior; this way only this action occurs
index--; // decrement the index of set by one
if (0 > index) {index = aSet.length-1;} // if exceeding the minimum length of the set, index should wrap to the last value
that.changeImage(); // call global Function to actually change the image
}
};
// Public methods and constants
F.prototype = {
/**
* function to call when adding an image to a set; the last image added determines the set that is active
* @public
*/
addImage: function(group, url) {
// is there a data set for group of images; when no, add one to the 'data' Object
if (! data[group]) {
data[group] = []; // creates a new Array to fill with Images
}
aSet = data[group]; // retrieves the set (Array of Images) for group
var img = new Image(); // creates a new instance of Image
img.src = url; // links the Image Object to the image URL
aSet.push(img); // appends the Image Object into the set
},
/**
* function to change the image to the one in the current set @ index
* @public
*/
changeImage: function() {
var img = aSet[index].image; // grab the Image from active set @ index
dom.img.src = img.src; // actually change the image
// update the caption, when present
if (dom.cap) {
dom.cap.innerHTML = aSet[index].caption || '';
}
},
/**
* function to call when switching from one set to another
* @public
*/
changeSet: function(group) {
var o = data[group];
if (YAHOO.lang.isArray(o)) { // verify that 'group' is a valid set
index = 0; // reset the index
aSet = o; // change the set to that of group
that.changeImage(); // update the image
}
else {
alert('You are trying to change to an image set that is not defined: ' + group);
}
}
};
that = new F();
// attach the next and previous events
$E.on(dom.next, 'click', evt.onNext);
$E.on(dom.prev, 'click', evt.onPrev);
// iterate through the data sets to find the Image that is initially visible
for (var k in data) {
if (data.hasOwnProperty(k)) {
var o = data[k],
changeLink = $(k); // retrieve the set chooser 'a' tag from DOM
// ensure that the required 'a' tag exists and attach onChange event
if (changeLink) {
$E.on(changeLink, 'click', evt.onChange);
}
// if data isn't an array, then we expect the change links to be present in the DOM
else if (! isArray) {
alert('PhotoViewer Error - required set chooser link is missing for: ' + k);
}
for (var i = o.length - 1; 0 <= i; i -= 1) {
var img = new Image(); // creates a new instance of Image
img.src = o[i].image || o[i]; // links the Image Object to the image URL
o[i] = {image: img, caption: o[i].caption};
dom.hnode.appendChild(img); // adding to DOM to force image to cache
if (o[i].image.src === dom.img.src) {
index = i;
aSet = o;
}
}
}
}
if (! aSet.length) {
alert('Warning: the initial image (' + dom.img.src + ') was not added to the image collection.');
}
return that;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment