Slideshow - an example of a maintainable, unobtrusive JavaScript solution

Step 4: The Script

Now that we have all the tool methods in place and init() gets called when the window has finished loading, we can start fleshing out the method.

Notice that this is only the init() method, not the whole script. Copying and pasting will also result in errors as there are line numbers!

  1: init:function(){
  2:   if(document.getElementById && 
          document.createTextNode){
  3:     var list = document.getElementById('slideshow');
  4:     if(list){
  5:       slideshow.items = list.getElementsByTagName('li');
  6:       slideshow.all = slideshow.items.length;
  7:       if(slideshow.all > 1){
  8:         slideshow.addClass(list, 'js');
  9:         slideshow.createNav(list);
 10:       }
 11:     }
 12:     slideshow.show();
 13:   }  
 14: },
  • Line 2 tests if the DOM is supported.
  • Lines 3 and 4 tries to retrieve the element with the ID slideshow and does not execute the rest of the method when it is not defined.
  • Lines 5 and 6 retrieve the list of items and the number of all items in the list and store them in the properties items and all respectively.
  • Line 7 tests if there is more than one list item and does not execute the rest if there isn't
  • Line 8 adds the js class to the list - thus hiding the list items and applying the different styling.
  • Line 9 calls createNav() and provides the list as a parameter.
  • Line 12 calls show() to show the slide predefined in the current property

The createNav() method uses DOM scripting to generate all the HTML necessary for the slideshow to work (¬ is an enforced linebreak).

  1: createNav:function(o){
  2:   var p = document.createElement('p');
  3:   slideshow.addClass(p, 'slidenav');
  4:   slideshow.prev = document.createElement('a');
  5:   slideshow.prev.setAttribute('href', '#');
  6:   var templabel = document.createTextNode('<<');
  7:   slideshow.prev.appendChild(templabel);
  8:   slideshow.addEvent(slideshow.prev, 'click', ¬
       slideshow.show);		
  9:   p.appendChild(slideshow.prev);
 10:   slideshow.count = document.createElement('span');
 11:   templabel = document.createTextNode( ¬
       (slideshow.current+1) + ' / ' + slideshow.all);
 12:   slideshow.count.appendChild(templabel);
 13:   p.appendChild(slideshow.count);
 14:   slideshow.next = document.createElement('a');
 15:   slideshow.next.setAttribute('href', '#');
 16:   var templabel = document.createTextNode('>>');
 17:   slideshow.next.appendChild(templabel);
 18:   slideshow.addEvent(slideshow.next, 'click', ¬
       slideshow.show);		
 19:   p.appendChild(slideshow.next);
 20:   o.parentNode.insertBefore(p, o);
 21: },
  • Line 2 and 3 start with creating a P element which will host the whole slideshow navigation and apply a class called slidenav to it.
  • Line 4 and 5 create a new link element, store it in a property called prev and set a # as the href attribute. This is necessary to make the link appear as a real link and keyboard accessible.
  • Line 6 creates a new text label and line 7 adds it to the link.
  • Line 8 adds an event handler pointing the the show() listener method.
  • Line 9 appends the new link to the paragraph
  • Next is the counter, and we start in line 10 by creating a SPAN element and storing it in the count property.
  • Line 11 creates a new text node showing which slide of how many is currently displayed. We have to add 1 to the current property as humans start counting at 1 and not at 0.
  • Line 12 adds the label as a new child to the SPAN and line 13 adds that one to the paragraph.
  • Line 14 to line 19 are basically a copy of 4 to 9, only this time the newly created link has a different text label and is stored in the next property.
  • Line 20 inserts the newly created paragraph before the original image list in the document.

That is all the necessary markup created, all that is left to do is to define a listener method called show() which reacts to the links being clicked.

  1: show:function(e){
  2: if(this === slideshow.next || this === slideshow.prev){
  3:   slideshow.removeClass( ¬
       slideshow.items[slideshow.current], 'current');
  4:   var addto = (this === slideshow.next) ? 1 : -1;
  5:   slideshow.current = slideshow.current + addto;
  6:   if(slideshow.current < 0){
  7:     slideshow.current = (slideshow.all-1);
  8:   }
  9:   if(slideshow.current > slideshow.all-1){
 10:     slideshow.current = 0;
 11:   }
 12: }
 13: var templabel = document.createTextNode( ¬
     (slideshow.current+1) + ' / ' + slideshow.all);
 14: slideshow.count.replaceChild(templabel, ¬ 
     slideshow.count.firstChild);
 15: slideshow.addClass(slideshow.items[slideshow.current], ¬
     'current');
 16: slideshow.cancelClick(e);
 17: },
  • Line 1 gets the current event object as the parameter e. This is only necessary to call cancelClick() later on.
  • Line 2 tests if the clicked element was either the next or the previous link (this is returned by addEvent())
  • Line 3 removes the current class from the currently shown slide. As there was a clicked link this will be possible.
  • Line 4 determines whether the current counter should be increased or decreased by comparing this with the next property and line 5 modifies the counter accordingly.
  • Line 6 to 11 make sure that the counter will never be out of bounds by setting it to the last slide when you are on the first and hit previous and to the first when you hit next on the last slide.
  • Lines 13 and 14 assemble a new state of the counter text and replace the old one.
  • Line 15 shows the new current slide by appending the current class.
  • Line 16 stops the link from being followed by calling cancelClick().

That is all there is to this script, you can see it in its full glory by downloading slideshow-plain.js and slideshow.css.

The script works, but is not really maintainable yet.

Creative Commons License This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License. Written by Christian Heilmann, CSS based on the Yahoo! User Interface Library