The continued adventures of the Permalink slideshow

In implementing the permalink slideshow for a few projects at work, it is now improved and a lot easier to set up. You can find the most recent version of the code here: http://natbat.net/code/clientside/js/permalinkSlideshow/slideshow.js (working example)

The idea now is that if you just follow a simple structure for your html, and create an additional stylesheet (that is imported with javascript) then all you need is the relevant javascript files (the slideshow one and the relevant YUI ones) and it should just work.

The script now relies on the Yahoo User interface library as this allowed for funkier effects other than just the linear fade I had wrote myself, as well as events and helper functions and the like. Naturally it is not perfect and there is still quite a bit that can be improved (such as the issue with conflicting namespaces) but it is definitely more customisable than it was and not such a nightmare to set up.

For the slideshow script to work you will need the Yahoo library’s: ‘yahoo’, ‘dom’, ‘event’ and ‘animation’ to be imported before your slideshow js file (http://developer.yahoo.com/yui/)

<script type="text/javascript" src="/javascript/YUI/yahoo-min.js"></script>
<script type="text/javascript" src="/javascript/YUI/dom-min.js"></script>
<script type="text/javascript" src="/javascript/YUI/event-min.js"></script>
<script type="text/javascript" src="/javascript/YUI/animation-min.js"></script>
<script type="text/javascript" src="/javascript/slideshowFile.js"></script>

At the top of the new slideshow javascript file there are a number of global variables that are explained in the code, these control the hooks for the script and elements of its behaviour.

The compulsory variables are:

  • u_fadeSlide - specifies how long the fade transition between slides will take - setting this variable to between 0.3 and 0.5 for a fade works nicely.
  • u_importedCSSfile - the path from the root to the css file to import
  • u_slideName - this is the initial id of your slide, without the number, the url may look like … http://yourSite.com#slideName1 your slides will also need u_slideName as a classname
  • u_slideTitlePrefix - this is the long title for your slide, it appears on the title bar
  • u_slideContainerID - the containing div for your slides.

If you set u_fadeSlide to 0 the fade will be instantaneous and you need to take this into consideration when deciding if the height should be fixed or not, if the height cannot remain constant between slides (and you still *really* want fading) I will need to do more jiggery pokery in order to get it to work. At the moment the fade will only work with fixed height slides because currently they need to be positioned absolutely.

Your document will then need to follow the structure:

   <div id="u_slideContainerID">
       <div id="u_slideName1" class="u_slideName">
           <!-- some sort of slide, an image or text or whatever -->
       </div>
       <div id="u_slideName2" class="u_slideName">
           <!-- some sort of slide, an image or text or whatever -->
       </div>
       <div id="u_slideName3" class="u_slideName">
           <!-- some sort of slide, an image or text or whatever -->
       </div>
       <div id="u_slideName4" class="u_slideName">
           <!-- some sort of slide, an image or text or whatever -->
       </div>

       <!-- and on and on and on ..... (you can have other div's in
here but not with the same class name or ID format)-->
   </div>

In the initial styles for the page you will need to find a way of displaying all your slides so that it looks good on one page, this is what it will look like without javascript, you will probably want to set the next and previous links as well as the ‘page X of X’ text to display: none however leave your navigational elements as a list of permalinks to allow for navigation by non script enabled browsers. Your slide navigation may well resemble:

	<ol id="u_navList">
		<li><a href="u_slideName1">1</a></li>
	</ol>

In the css set the className ’selected’ for the links in the above list to have some special style as this will be set with the JS for the slide that you are currently on. In the imported CSS you will need to override the display: none’s you did for the pages and next previous etc. (These aren’t added dynamically btw because they could be anywhere in the page for a new version of this) then you want to make all the slides stack up on top of each other. One way to do this is to have the #u_slideContainerID div set to position relative and the individual .u_slideName set to position: absolute; top:0; You will need to set the slides to display: none and slide 1 to display: block so it doesn’t jump too much as the page loads (you may also need to set #slideshowSlide1 to display: block) the Javascript will work out the rest.

An imported css file for a set of fading slides of all the same height might look something like:

   #u_slideContainerID {
       position: relative;
       height: 200px;
       overflow: hidden;
   }

   #u_slideContainerID .u_slideName {
       position: absolute;
       top: 0;
       display: none;
   }

   #u_slideContainerID #u_slideName1,
   #u_slideContainerID #slideshowSlide1  {
       display: block;
   }

Whereas you could miss the positioning and the height off if you are setting the u_fadeSlide (the time between fades) to 0 so that the slide takes up its natural height:

   #u_slideContainerID {
       position: relative;
   }

   #u_slideContainerID .u_slideName {
       display: none;
   }

   #u_slideContainerID #u_slideName1,
   #u_slideContainerID #slideshowSlide1  {
       display: block;
   }

The optional parameters can be left blank if not required but will not break the page if they are not accurate. These include:

  • u_nextLink - the id or ids of the nextlink link elements, if more than one next link provide a comma separated list, e.g. ‘id1,id2′
  • u_previousLink - as above but with the previous page links
  • u_navList - id of list for permalink paging elements, comma separated id list again
  • u_pages - id of the paragraph where you want to put the text ‘Page X of X’ where the word ‘page is replaced with u_slideName, e.g. ‘chapter 1 of 7′

Printing the entire document like you can here on wrap is quite easy too, you need a function that removes the link to the imported stylesheet and you may also need to import a new stylesheet for printing, I haven’t included a print function in this version yet though, as I said, its not quite perfect.

Looking at how it works, starting from the bottom up it attaches the imported stylesheet with a try catch instead of an onload event to avoid any flicker of styles:

function setCSS(css) {
	try {
		// append stylesheet to alter
		document.getElementsByTagName("head")[0].appendChild(css);
	} catch (e) {
		setTimeout(function(){setCSS(css)}, 100);
	}
}

// create CSS element to set up the page
var css = document.createElement(”link”);
css.setAttribute(”href”,u_importedCSSfile);
css.setAttribute(”rel”,”stylesheet”);
css.setAttribute(”type”,”text/css”);

// attempt to add the css and then keep trying till we do
setCSS(css);
css = null;

An onload listener then initiates the startup function which sets the whole thing going, it assigns all the id’s of the slides to be in the form ’slideshowSlide’, it needs to have a different id in order to avoid a jump in IE. It then identifies what slide we are supposed to be on if any, through the hash of the URL. Setting the title of the page and assigning the navigation is the next step, write what page we are on then display the current slide. The last step of the startup function is to set up an interval checker to listen to any changes in the URL.

Nothing happens then until a slide is requested, either through clicking the next previous links, changing the URL hash or using the permalink navigation. When this occurs (listeners set up in the initial call to the assign navigation function) the startFade function sets a global variable to indicate there is a fade in process, nothing can happen until it finishes, if it is ok for the fade to proceed it sets ever slide except the current slide to be display:none and visibility: hidden, then it sets the requested slide to appear but as this has a lower z-index it is currently below the slide we are on.

If the fade time is 0 it simply swaps the slides, otherwise it uses the YUI to fade the top slide out revealing the requested slide:

// fade the top slide onto the bottom
var anim = new YAHOO.util.Anim(gSlides[gCurrentSlide],
    { opacity: { from: 1, to: 0 } }, u_fadeSlide, YAHOO.util.Easing.easeBoth);
anim.onComplete.subscribe(function() { insEndFade(requestedSlide) });
anim.animate();
anim = null;

The end fade function then sorts out the rest, resets the navigation, what page we are on, the page title and unsets the global fade variable to allow other fades to occur, finally restarting the URL checker to listen for changes to the URL.

So I hope that code this helps you if there is a need to have a fading slideshow, or even any kind of unobtrusive permalink pageable application, let me know if you have any trouble with it or have found a way of making it better!

3 Responses

  1. That’s pretty slick. nice writeup, too.
    I like how you’re clicking #’s too, and not next pages.
    Is there a way to use jeremy’s DOM to bypass a #link ?

    luxuryluke - November 19th, 2006 at 6:27 pm
  2. [...] In response to PPK’s 24 ways article I thought I should describe the method I currently choose employ to hide elements onload. I have gone through this briefly in my article ‘releasing the permalink slideshow‘. As PPK mentioned, it is important to hide elements not needed for browsers that don’t support JavaScript. The most important part of this hide technique is that there is no flicker in the period that the page is being loaded. [...]

    Natalie Downe » Blog Archive » Reliably attaching CSS - December 6th, 2006 at 5:50 pm
  3. [...] Natalie Downe » Blog Archive » The continued adventures of the Permalink slideshow (tags: slideshow) [...]

    JEDI » Blog Archive » links for 2007-01-02 - January 2nd, 2007 at 10:19 am

Leave a Reply