Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Tuesday, August 5, 2008

Simple Image Viewer With Captions

It seems that, if I am to leave a legacy after this blog is gone, it will be my Super Simple Image Viewer, as more people read and ask about this widget than any other part of this blog. I attempted to address most people concerns in last weeks Somewhat Simple Image Viewer article, but I was only partially successful, as I did not add in the second most requested feature: captions. So I went back to the drawing board and have written a third version of the Image Viewer.

Version 3 supports both single collection and multiple collections of images (such as portfolios or events), and captions are optional. This way it is nearly backwards compatible with Version 2 that we discussed last week.

Users will quickly notice that the PhotoViewer Function now only requires two parameters: ‘cfg’ and ‘data’. Where ‘cfg’ is an Object containing DOM references and ‘data’ is the collection of image URLs (and other meta data). Below is an example of the ‘cfg’ Object:

Example 1: Configuration Object

var cfg = { caption: 'viewer-caption', // optional image: 'viewer-image', // required next: 'viewer-next', // required prev: 'viewer-prev' // required };

While the caption value is optional, if any of the other 3 DOM references are missing, PhotoViewer will alert you and not initialize. The ‘data’ can be in two different formats, first it can just be a Array of image URLs, second it can be an Object where each key is the DOM ID of the anchor tag to select that set and the value is the Array of images. Here are 3 different valid data sets:

Example 2: Data Object

// 3 sets of objects, containing the image and caption var data = { set1: [// this needs to be the DOM ID attribute for the anchor tag to select this set {image: 'http://farm1.static.flickr.com/142/331222000_76f271e745.jpg?v=0', caption: 'frozen landscape'}, {image: 'http://farm1.static.flickr.com/159/384269775_f8b21b5e52.jpg?v=0', caption: 'mountain stream'}, {image: 'http://farm1.static.flickr.com/178/415791942_4a4e411464.jpg?v=0', caption: 'mountain lake'} ], set2: [// this needs to be the DOM ID attribute for the anchor tag to select this set {image: 'http://farm1.static.flickr.com/186/421171930_80ef8ee7b2.jpg?v=0', caption: 'cool canpopy'}, {image: 'http://farm1.static.flickr.com/155/421172107_2f20ec7aeb.jpg?v=0', caption: 'cool tree'}, {image: 'http://farm1.static.flickr.com/54/133256387_e99cd967ff.jpg?v=0', caption: 'vibrant rose'} ], set3: [// this needs to be the DOM ID attribute for the anchor tag to select this set {image: 'http://farm1.static.flickr.com/46/167939744_2357ffe1af.jpg?v=0', caption: 'white mountains'}, {image: 'http://farm1.static.flickr.com/48/177853809_ad9454a89e.jpg?v=0', caption: 'small turtle'}, {image: 'http://farm1.static.flickr.com/54/183725415_ff609f45e4.jpg?v=0', caption: 'mountain sunset'} ] }; // 3 sets of image URLs var data2 = { set4: // this needs to be the DOM ID attribute for the anchor tag to select this set ['http://farm1.static.flickr.com/142/331222000_76f271e745.jpg?v=0', 'http://farm1.static.flickr.com/159/384269775_f8b21b5e52.jpg?v=0', 'http://farm1.static.flickr.com/178/415791942_4a4e411464.jpg?v=0'], set5: // this needs to be the DOM ID attribute for the anchor tag to select this set ['http://farm1.static.flickr.com/186/421171930_80ef8ee7b2.jpg?v=0', 'http://farm1.static.flickr.com/155/421172107_2f20ec7aeb.jpg?v=0', 'http://farm1.static.flickr.com/54/133256387_e99cd967ff.jpg?v=0'], set6: // this needs to be the DOM ID attribute for the anchor tag to select this set ['http://farm1.static.flickr.com/46/167939744_2357ffe1af.jpg?v=0', 'http://farm1.static.flickr.com/48/177853809_ad9454a89e.jpg?v=0', 'http://farm1.static.flickr.com/54/183725415_ff609f45e4.jpg?v=0'] }; // an array of image URLs var data3 = [ 'http://farm1.static.flickr.com/142/331222000_76f271e745.jpg?v=0', 'http://farm1.static.flickr.com/159/384269775_f8b21b5e52.jpg?v=0', 'http://farm1.static.flickr.com/178/415791942_4a4e411464.jpg?v=0', 'http://farm1.static.flickr.com/186/421171930_80ef8ee7b2.jpg?v=0', 'http://farm1.static.flickr.com/155/421172107_2f20ec7aeb.jpg?v=0', 'http://farm1.static.flickr.com/54/133256387_e99cd967ff.jpg?v=0', 'http://farm1.static.flickr.com/46/167939744_2357ffe1af.jpg?v=0', 'http://farm1.static.flickr.com/48/177853809_ad9454a89e.jpg?v=0', 'http://farm1.static.flickr.com/54/183725415_ff609f45e4.jpg?v=0' ];

Data set 1 shows how to add captions into your PhotoViewer, while set 2 is exactly the same as we used last week, and set 3 is supported to for those of you who don’t need multiple image collections. You can see an example of all 3, Image Viewer Example and the JavaScript code here. Also, to support this more powerful version, I needed extra library code, and you will need to include the following 3 files before importing the PhotoViewer script.

Example 3: JavaScript Files to Include

// core dom and event framework <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/yahoo-dom-event/yahoo-dom-event.js"></script> // required for type detection <script type='text/javascript' src="http://www.mattsnider.com/assets/js/core/type.js"></script> // required for object manipulation <script type="text/javascript" src="http://www.mattsnider.com/assets/js/object.js"></script>

Lastly, version 3 has a brand new feature, that improves the initial performance of the PhotoViewer widget. I have noticed that in some browsers, like FF2+, even though we are pre-caching the images (using circa 1999 technology), the first time we clicked to see an image it takes an exceptionally long time to load, as if it wasn’t pre-cached (and it probably isn’t). Browsers have become rather smart and to improve performance they don’t always download files, when they don’t believe they are necessary. Therefore, to defeat the browser intelligence, I have created a hidden node at the end of the body tag, in which we will append each image that we want to cache. This tricks the browser into downloading (and pre-caching) the images, thereby drastically improving the performance the first time iterates through the images in PhotoViewer.

posted by Matt Snider at 9:56 am  

5 Comments »

  1. got this one working fine!

    great job.

    Comment by Thom — August 5, 2008 @ 1:16 pm

  2. I’m having a small issue and I don’t understand why.
    The links to my different portfolios work fine if I use text links… but if I use an image as a link I get an error when I actually click the link in a brower.

    The error reads…
    [ Javascript Application]
    You are trying to change to an imjage set that is not defined:

    Here is my code for my first link

    (this is what it looks like when i get the error)

    Portfolio 1
    (this is what it looks like when it works.)

    I’m very confused!

    Comment by Thom — August 14, 2008 @ 2:24 pm

  3. ()

    oops forgot you wouldnt be able to see the code (not too code savvy)
    that’s how it looks when it doesn’t work besides the () obviously

    Comment by Thom — August 14, 2008 @ 2:27 pm

  4. Well I messed that up again!

    I also have another question.

    The image viewer will not function if I try to add more then 3 images per portfolio.
    How do I fix that?

    Comment by Thom — August 14, 2008 @ 3:32 pm

  5. Thom,

    For comment 2 & 3, the error you are seeing usually happens when you don’t have the right ID attribute on your portfolio anchor tag. The portfolio name when you are setting up your data set should be the same as the ID attribute for the anchor tag you use to select that portfolio. I don’t see any IDs in the anchors you provided.

    For comment 4, I cannot reproduce your issue. You’ll have to post your data object; wrap it in a <code>your code</code> so the HTML is escaped. My guess is that you are missing a comma or something like that, but you should be able to add as many images to each array as you want.

    Comment by Matt Snider — August 15, 2008 @ 9:07 am

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress