The Lodge is members-only design/dev videos and Office Hours.

Next Office Hours Session: "Implementing an SVG Icon System" Nov 30 - 6:00 PM Eastern

Galleria Plugin / JQuery help please (and Thankyou!)

  • # August 17, 2009 at 9:04 am

    Hey guys, I’m dipping my toe into JQuery and am fooling around with the galleria plugin (you can view the beast in it’s natural element at I’ve copied the code over to my testbed fairly faithfully, but have made some changes to the layout, dimensions, etc.. You can view that here

    I have also, however, tried to add two little effects of my own and I’m afraid I’m making a sad mess of it:

    In the initial version, the title attr of the image was pulled and placed in a span underneath the main image, in my version I’ve placed it in a div and given it a scroll-type animation to reveal itself upon the mouse hovering over the main image. So far so good, but now this text is without <p> or <span> tags and difficult to style exactly. I’ve tried append, ‘wrapinner’, etc, and even tried to create a new element (i.e. a <p>) and insert it within the div I created previously, but without the proper know-how that just wasn’t working. I’ve left it without any tags for the moment, but any help here would be great.

    My second problem is that, in giving the main image a hover function, I’ve obviously conflicted with the initial version’s method which was to display a tool tip ("Next Image>>") and activated to next image on mouseclick. What I want is to wrap the images in an anchor tag to lead to a page dedicated to that image’s subject matter and to have the JQuery pull that anchor link, hide it , and then activate it when someone clicks on the main image. Changing the content of the tooltip is (thankfully!) not a prob.

    I’m including below all the coding involved, for which I apologise in advance. I’m just at the very, very beginning of learning this stuff and I’m not 100% as to what’s relevant or not…

    Firstly, the image list, without anchor tags:


    Then the header content:


    And finally, the plugin code itself. I understand it in pieces, but unfortunately get lost along the way :D !:

    * Copyright (c) 2008 David Hellsing (
    * Licensed under the GPL licenses.


    var $$;

    $$ = $.fn.galleria = function($options) {

    // check for basic CSS support
    if (!$$.hasCSS()) { return false; }

    // init the modified history object

    // set default options
    var $defaults = {
    insert : ‘.galleria_container’,
    history : true,
    clickNext : true,
    onImage : function(image,caption,thumb) {},
    onThumb : function(thumb) {}

    // extend the options
    var $opts = $.extend($defaults, $options);

    // bring the options to the galleria object
    for (var i in $opts) {
    $.galleria[i] = $opts[i];

    // if no insert selector, create a new division and insert it before the ul
    var _insert = ( $($opts.insert).is($opts.insert) ) ?
    $($opts.insert) :

    // create a wrapping div for the image
    var _div = $(document.createElement(‘div’)).addClass(‘galleria_wrapper’);

    // create a caption div
    var _titlediv = $(document.createElement(‘div’)).addClass(‘caption’);

    // inject the wrapper in in the insert selector


    return this.each(function(){

    // add the Galleria class

    // loop through list
    $(this).children(‘li’).each(function(i) {

    // bring the scope
    var _container = $(this);

    // build element specific options
    var _o = $.meta ? $.extend({}, $opts, : $opts;

    // remove the clickNext if image is only child
    _o.clickNext = $(this).is(‘:only-child’) ? false : _o.clickNext;

    // try to fetch an anchor
    var _a = $(this).find(‘a’).is(‘a’) ? $(this).find(‘a’) : false;

    // reference the original image as a variable and hide it
    var _img = $(this).children(‘img’).css(‘display’,’none’);

    // extract the original source
    var _src = _a ? _a.attr(‘href’) : _img.attr(‘src’);

    // find a title
    var _title = _a ? _a.attr(‘title’) : _img.attr(‘title’);

    // create loader image
    var _loader = new Image();

    // check url and activate container if match
    if (_o.history && (window.location.hash && window.location.hash.replace(/#/,”) == _src)) {

    // begin loader
    $(_loader).load(function () {

    // try to bring the alt

    // the image is loaded, let’s create the thumbnail

    var _thumb = _a ?
    _a.find(‘img’).addClass(‘thumb noscale’).css(‘display’,’none’) :

    if (_a) { _a.replaceWith(_thumb); }

    if (!_thumb.hasClass(‘noscale’)) { // scaled tumbnails!
    var w = Math.ceil( _img.width() / _img.height() * _container.height() );
    var h = Math.ceil( _img.height() / _img.width() * _container.width() );
    if (w < h) { _thumb.css({ height: '72px', width: '115px', marginTop: '10px', marginLeft: '10px' }); } else { _thumb.css({ width: '115px', height: '72px', marginLeft: '10px', marginTop: '10px' }); } } else { // Center thumbnails. // a tiny timer fixed the width/height window.setTimeout(function() { _thumb.css({ marginLeft: -( _thumb.width() - _container.width() )/2, marginTop: -( _thumb.height() - _container.height() )/2 }); }, 1); } // add the rel attribute _thumb.attr('rel',_src); // add the title attribute _thumb.attr('title',_title); // add the click functionality to the _thumb { $.galleria.activate(_src); }); // hover classes for IE6 _thumb.hover( function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); } ); _container.hover( function() { _container.addClass('hover'); }, function() { _container.removeClass('hover'); } ); // prepend the thumbnail in the container _container.prepend(_thumb); // show the thumbnail _thumb.css('display','block'); // call the onThumb function _o.onThumb(jQuery(_thumb)); // check active class and activate image if match if (_container.hasClass('active')) { $.galleria.activate(_src); //_titlediv.text(_title); } //----------------------------------------------------------------- // finally delete the original image _img.remove(); }).error(function () { // Error handling _container.html('Error loading image: ‘+_src+’‘);

    }).attr(‘src’, _src);

    * @name NextSelector
    * @desc Returns the sibling sibling, or the first one

    $$.nextSelector = function(selector) {
    return $(selector).is(‘:last-child’) ?
    $(selector).siblings(‘:first-child’) :


    * @name previousSelector
    * @desc Returns the previous sibling, or the last one

    $$.previousSelector = function(selector) {
    return $(selector).is(‘:first-child’) ?
    $(selector).siblings(‘:last-child’) :


    * @name hasCSS
    * @desc Checks for CSS support and returns a boolean value

    $$.hasCSS = function() {
    .css({ width:’1px’, height:’1px’, display:’none’ })
    var _v = ($(‘#css_test’).width() != 1) ? false : true;
    return _v;

    * @name onPageLoad
    * @desc The function that displays the image and alters the active classes
    * Note: This function gets called when:
    * 1. after calling $.historyInit();
    * 2. after calling $.historyLoad();
    * 3. after pushing “Go Back” button of a browser

    $$.onPageLoad = function(_src) {

    // get the wrapper
    var _wrapper = $(‘.galleria_wrapper’);

    // get the thumb
    var _thumb = $(‘.galleria img[@rel=”‘+_src+'”]’);

    if (_src) {

    // new hash location
    if ($.galleria.history) {
    window.location = window.location.href.replace(/#.*/,”) + ‘#’ + _src;

    // alter the active classes

    // define a new image
    var _img = $(new Image()).attr(‘src’,_src).addClass(‘replaced’);

    // empty the wrapper and insert the new image

    // insert the caption

    // fire the onImage function to customize the loaded image’s features

    // add clickable image helper
    if($.galleria.clickNext) {
    _img.css(‘cursor’,’pointer’).click(function() { $; })

    } else {

    // clean up the container if none are active

    // remove active classes

    // place the source in the galleria.current variable
    $.galleria.current = _src;


    * @name jQuery.galleria
    * @desc The global galleria object holds four constant variables and four public methods:
    * $.galleria.history = a boolean for setting the history object in action with named URLs
    * $.galleria.current = is the current source that’s being viewed.
    * $.galleria.clickNext = boolean helper for adding a clickable image that leads to the next one in line
    * $ = displays the next image in line, returns to first image after the last.
    * $.galleria.prev() = displays the previous image in line, returns to last image after the first.
    * $.galleria.activate(_src) = displays an image from _src in the galleria container.
    * $.galleria.onImage(image,caption) = gets fired when the image is displayed.

    $.extend({galleria : {
    current : ”,
    onImage : function(){},
    activate : function(_src) {
    if ($.galleria.history) {
    } else {
    next : function() {
    var _next = $($$.nextSelector($(‘.galleria img[@rel=”‘+$.galleria.current+'”]’).parents(‘li’))).find(‘img’).attr(‘rel’);
    prev : function() {
    var _prev = $($$.previousSelector($(‘.galleria img[@rel=”‘+$.galleria.current+'”]’).parents(‘li’))).find(‘img’).attr(‘rel’);


    * Packed history extension for jQuery
    * Credits to

    jQuery.extend({historyCurrentHash:undefined,historyCallback:undefined,historyInit:function(callback){jQuery.historyCallback=callback;var current_hash=location.hash;jQuery.historyCurrentHash=current_hash;if(jQuery.browser.msie){if(jQuery.historyCurrentHash==”){jQuery.historyCurrentHash=’#’}$(“body”).prepend(‘‘);var ihistory=$(“#jQuery_history”)[0];var iframe=ihistory.contentWindow.document;;iframe.close();iframe.location.hash=current_hash}else if($.browser.safari){jQuery.historyBackStack=[];jQuery.historyBackStack.length=history.length;jQuery.historyForwardStack=[];jQuery.isFirst=true}jQuery.historyCallback(current_hash.replace(/^#/,”));setInterval(jQuery.historyCheck,100)},historyAddHistory:function(hash){jQuery.historyBackStack.push(hash);jQuery.historyForwardStack.length=0;this.isFirst=true},historyCheck:function(){if(jQuery.browser.msie){var ihistory=$(“#jQuery_history”)[0];var iframe=ihistory.contentDocument||ihistory.contentWindow.document;var current_hash=iframe.location.hash;if(current_hash!=jQuery.historyCurrentHash){location.hash=current_hash;jQuery.historyCurrentHash=current_hash;jQuery.historyCallback(current_hash.replace(/^#/,”))}}else if($.browser.safari){if(!jQuery.dontCheck){var historyDelta=history.length-jQuery.historyBackStack.length;if(historyDelta){jQuery.isFirst=false;if(historyDelta<0){for(var i=0;i
    =0){jQuery.historyCallback(document.URL.split(‘#’)[1])}else{var current_hash=location.hash;jQuery.historyCallback(”)}jQuery.isFirst=true}}}else{var current_hash=location.hash;if(current_hash!=jQuery.historyCurrentHash){jQuery.historyCurrentHash=current_hash;jQuery.historyCallback(current_hash.replace(/^#/,”))}}},historyLoad:function(hash){var newhash;if(jQuery.browser.safari){newhash=hash}else{newhash=’#’+hash;location.hash=newhash}jQuery.historyCurrentHash=newhash;if(jQuery.browser.msie){var ihistory=$(“#jQuery_history”)[0];var iframe=ihistory.contentWindow.document;;iframe.close();iframe.location.hash=newhash;jQuery.historyCallback(hash)}else if(jQuery.browser.safari){jQuery.dontCheck=true;this.historyAddHistory(hash);var fn=function(){jQuery.dontCheck=false};window.setTimeout(fn,200);jQuery.historyCallback(hash);location.hash=newhash}else{jQuery.historyCallback(hash)}}});

    Again, apologies for the long code, but any help you can give me would be greatly appreciated. I learn by doing, and I’m really liking what this JQuery can achieve…
    Ta! :D

    # August 17, 2009 at 12:10 pm

    This reply has been reported for inappropriate content.

    I’m certainly no jQuery expert, but I can usually get it to do what I want (eventually).

    So the first thing I did with the page was run it through the firebug console. You are getting one error:

    handler is undefined

    Now after a quick google search this looks like the most likely culprit

    All I can say for now is address that, then we’ll have another look and hopefully by then some of the javascript ninjas around here can come to your aid.

    # August 17, 2009 at 2:37 pm

    Aha! I saw that error myself, but had no idea what was causing it…

    That’s interesting – does that mean that you can’t actually use the hover event without specifying a mouseout function? Doesn’t that make ‘hover’ a bit pointless?

    EDIT – Ok changed the hover function to the following and got rid of that error:

    image.attr(‘title’,’Next image >>’); });

    image.attr(‘title’,’Next image >>’); });

    Any of you ninja’s have a crack at the rest? :D

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.

There's a whole bunch of content on CSS-Tricks.

Search for Stuff   •   Browse the Archives

Get the Newsletter ... or get the RSS feed