qc

AD

Build an Auto-Scrolling Slideshow That Works With and Without JavaScript

Wednesday, 29 May 2013
Create a jQuery slideshow that enables you to click through each slide when JavaScript is disabled, without having to display all slides one under the other.


Introduction

Final Product
There are several tutorials that walk people through how to create a jQuery slideshow, but there aren’t many
that focus on making it function without JavaScript. This is because most people believe it isn’t possible but
I am going to explain an exceedingly simple method that shows it is indeed possible. You’ll soon be
kicking yourself and asking “How did I not think of that?”…
In this tutorial I will cover the following:

Step 1: Writing the markup

First things first, we need to write the markup that our slideshow will use. So let’s jump straight
in and code it up:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
  2.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml">  
  4.     <head>  
  5.         <meta http-equiv="content-type" content="text/html; charset=utf-8" />  
  6.         <title>Tabbed jQuery slideshow</title>  
  7.           
  8.         <link rel="stylesheet" href="css/slideshow.css" type="text/css" media="screen" />          
  9.         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>  
  10.     </head>  
  11.     <body>  
  12.         <div id="slideshow">  
  13.             <div class="slides">  
  14.                 <ul>  
  15.                     <li>  
  16.                         <h2>Slide one</h2>  
  17.                         <p>  
  18.                             Lorem ipsum dolor sit amet, consectetur adipiscing elit.   
  19.                             Donec pretium arcu non velit. Phasellus adipiscing auctor   
  20.                             lorem. Curabitur in urna ut purus consequat sollicitudin.   
  21.                             Phasellus ut diam. Cras magna libero, tempor id, venenatis   
  22.                             sit amet, venenatis et, dui.  
  23.                         </p>  
  24.                     </li>  
  25.                     <li>  
  26.                         <h2>Slide two</h2>  
  27.                         <p>  
  28.                             Nam ac nibh sit amet augue ultricies sagittis. Donec sit   
  29.                             amet nunc. Vivamus lacinia, nisi ac tincidunt commodo, purus   
  30.                             nisi condimentum urna, sit amet molestie odio dolor non lectus.   
  31.                             Cum sociis natoque penatibus et magnis dis parturient montes,   
  32.                             nascetur ridiculus mus.  
  33.                         </p>  
  34.                     </li>     
  35.                     <li>  
  36.                         <h2>Slide three</h2>  
  37.                         <p>  
  38.                             Lorem ipsum dolor sit amet, consectetur adipiscing elit.   
  39.                             Suspendisse adipiscing dui a nibh. Integer tristique lorem   
  40.                             vitae massa. Etiam dapibus, eros sit amet euismod semper,   
  41.                             felis erat congue lacus, sed aliquam metus libero sed elit.  
  42.                         </p>  
  43.                     </li>                  
  44.                 </ul>  
  45.             </div>  
  46.             <ul class="slides-nav">  
  47.                 <li><a href="#">Slide one</a></li>  
  48.                 <li><a href="#">Slide two</a></li>  
  49.                 <li><a href="#">Slide three</a></li>  
  50.             </ul>  
  51.         </div>  
  52.     </body>  
  53. </html>     
This isn’t quite complete yet but as a general rule of thumb, we should
always start with the bare minimum and enhance/add to it when
necessary.

Step 2: Add some CSS

We’re not going to be creating the most beautiful slideshow today as I
just want to demonstrate the functionality more than anything. The
following styles will set up our slideshow ready for action:
  1. /* ---------------------------------------------------- */  
  2. /* GLOBAL 
  3. /* ---------------------------------------------------- */  
  4. html {  
  5. font-size: 76%;}  
  6.   
  7. body {  
  8. font-familyarialhelveticasans-serif;  
  9. line-height: 1.4em;  
  10. font-size: 1.2em;  
  11. padding: 5%;}  
  12.   
  13. /* ---------------------------------------------------- */  
  14. /* SLIDESHOW 
  15. /* ---------------------------------------------------- */  
  16. #slideshow {  
  17. width960px;  
  18. background-color#eee;  
  19. border1px solid #ddd;}  
  20.   
  21. #slideshow ul {  
  22. margin: 0;  
  23. padding: 0;  
  24. list-style-typenone;  
  25. height: 1%; /* IE fix */}  
  26.   
  27. #slideshow ul:after {  
  28. content".";  
  29. clearboth;  
  30. displayblock;  
  31. height: 0;  
  32. visibilityhidden;}              
  33.   
  34. /* ---------------------------------------------------- */  
  35. /* SLIDESHOW > SLIDES 
  36. /* ---------------------------------------------------- */  
  37. #slideshow .slides {  
  38. overflowhidden;  
  39. width960px;}  
  40.   
  41. #slideshow .slides ul {  
  42. /* total width of all slides - 
  43. 960px multiplied by 3 in this case */  
  44. width2880px;}  
  45.   
  46. #slideshow .slides li {  
  47. width920px;  
  48. floatleft;  
  49. padding20px;}  
  50.   
  51. #slideshow .slides h2 {  
  52. margin-top: 0;}  
  53.   
  54. /* ---------------------------------------------------- */  
  55. /* SLIDESHOW > NAVIGATION 
  56. /* ---------------------------------------------------- */  
  57. #slideshow .slides-nav {  
  58. background-color#ddd;  
  59. border-top2px solid #ccc;}  
  60.   
  61. #slideshow .slides-nav li {  
  62. floatleft;}  
  63.   
  64. #slideshow .slides-nav li a {  
  65. displayblock;  
  66. padding15px 20px;  
  67. outlinenone;}  
Add these styles to a slideshow.css stylesheet
in a CSS directory within the root. You should now see something
similar to this:
tabs

Step 3: Making it function without JavaScript

Some of you are probably wondering how on earth this is going to work
by now so I won’t make you wait any longer.
All we need to do is give each of our slides an ID and reference that
ID in the href attribute of the appropriate navigation item. It’s that
simple.
Your new markup should look as follows:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
  2.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml">  
  4.     <head>  
  5.         <meta http-equiv="content-type" content="text/html; charset=utf-8" />  
  6.         <title>Tabbed jQuery slideshow</title>  
  7.           
  8.         <link rel="stylesheet" href="css/slideshow.css" type="text/css" media="screen" />          
  9.         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>  
  10.     </head>  
  11.     <body>  
  12.         <div id="slideshow">  
  13.             <div class="slides">  
  14.                 <ul>  
  15.                     <li id="slide-one">  
  16.                         <h2>Slide one</h2>  
  17.                         <p>  
  18.                             Lorem ipsum dolor sit amet, consectetur adipiscing elit.   
  19.                             Donec pretium arcu non velit. Phasellus adipiscing auctor   
  20.                             lorem. Curabitur in urna ut purus consequat sollicitudin.   
  21.                             Phasellus ut diam. Cras magna libero, tempor id, venenatis   
  22.                             sit amet, venenatis et, dui.  
  23.                         </p>  
  24.                     </li>  
  25.                     <li id="slide-two">  
  26.                         <h2>Slide two</h2>  
  27.                         <p>  
  28.                             Nam ac nibh sit amet augue ultricies sagittis. Donec sit   
  29.                             amet nunc. Vivamus lacinia, nisi ac tincidunt commodo, purus   
  30.                             nisi condimentum urna, sit amet molestie odio dolor non lectus.   
  31.                             Cum sociis natoque penatibus et magnis dis parturient montes,   
  32.                             nascetur ridiculus mus.  
  33.                         </p>  
  34.                     </li>     
  35.                     <li id="slide-three">  
  36.                         <h2>Slide three</h2>  
  37.                         <p>  
  38.                             Lorem ipsum dolor sit amet, consectetur adipiscing elit.   
  39.                             Suspendisse adipiscing dui a nibh. Integer tristique lorem   
  40.                             vitae massa. Etiam dapibus, eros sit amet euismod semper,   
  41.                             felis erat congue lacus, sed aliquam metus libero sed elit.  
  42.                         </p>  
  43.                     </li>                  
  44.                 </ul>  
  45.             </div>  
  46.             <ul class="slides-nav">  
  47.                 <li><a href="#slide-one">Slide one</a></li>  
  48.                 <li><a href="#slide-two">Slide two</a></li>  
  49.                 <li><a href="#slide-three">Slide three</a></li>  
  50.             </ul>  
  51.         </div>  
  52.     </body>  
  53. </html>           
Now test out your new code by clicking each tab… How cool is that?
This is by no means an undiscovered technique. People are already using
it on sites you have probably used without realising, such as the
Coda website.

Step 4: Adding Some Animation

Right well, that was fun! Now it’s time to add some funky sliding animations
to our slideshow.
You’ll need to download the
minified
jQuery Cycle plugin
 that includes all transitions and save it as jquery.cycle.js
within a ‘js’ directory in your project root. Then add the following to your
<head> below the jquery library script tag.
  1. <script type="text/javascript" src="js/jquery.cycle.js"></script>  
  2. <script type="text/javascript" src="js/slideshow.js"></script>  
We’ll now create the slideshow.js file mentioned above and save it in the
‘js’ directory with the following code:
  1. $slideshow = {  
  2.     context: false,  
  3.     tabs: false,  
  4.     timeout: 1000,      // time before next slide appears (in ms)  
  5.     slideSpeed: 1000,   // time it takes to slide in each slide (in ms)  
  6.     tabSpeed: 300,      // time it takes to slide in each slide (in ms) when clicking through tabs  
  7.     fx: 'scrollLeft',   // the slide effect to use  
  8.       
  9.     init: function() {  
  10.         // set the context to help speed up selectors/improve performance  
  11.         this.context = $('#slideshow');  
  12.           
  13.         // set tabs to current hard coded navigation items  
  14.         this.tabs = $('ul.slides-nav li'this.context);  
  15.           
  16.         // remove hard coded navigation items from DOM   
  17.         // because they aren't hooked up to jQuery cycle  
  18.         this.tabs.remove();  
  19.           
  20.         // prepare slideshow and jQuery cycle tabs  
  21.         this.prepareSlideshow();  
  22.     },  
  23.       
  24.     prepareSlideshow: function() {  
  25.         // initialise the jquery cycle plugin -  
  26.         // for information on the options set below go to:   
  27.         // http://malsup.com/jquery/cycle/options.html  
  28.         $("div.slides > ul", $slideshow.context).cycle({  
  29.             fx: $slideshow.fx,  
  30.             timeout: $slideshow.timeout,  
  31.             speed: $slideshow.slideSpeed,  
  32.             fastOnEvent: $slideshow.tabSpeed,  
  33.             pager: $("ul.slides-nav", $slideshow.context),  
  34.             pagerAnchorBuilder: $slideshow.prepareTabs,  
  35.             before: $slideshow.activateTab,  
  36.             pauseOnPagerHover: true,  
  37.             pause: true  
  38.         });              
  39.     },  
  40.       
  41.     prepareTabs: function(i, slide) {  
  42.         // return markup from hardcoded tabs for use as jQuery cycle tabs  
  43.         // (attaches necessary jQuery cycle events to tabs)  
  44.         return $slideshow.tabs.eq(i);  
  45.     },  
  46.   
  47.     activateTab: function(currentSlide, nextSlide) {  
  48.         // get the active tab  
  49.         var activeTab = $('a[href="#' + nextSlide.id + '"]', $slideshow.context); 
  50.          
  51.         // if there is an active tab 
  52.         if(activeTab.length) { 
  53.             // remove active styling from all other tabs 
  54.             $slideshow.tabs.removeClass('on'); 
  55.              
  56.             // add active styling to active button 
  57.             activeTab.parent().addClass('on');  
  58.         }              
  59.     }              
  60. };  
  61. $(function() {  
  62.     // initialise the slideshow when the DOM is ready  
  63.     $slideshow.init();  
  64. });  

NOTE: To keep this tutorial short, I won’t explain everything
in this new javascript file but if you have any questions, feel free
to ask in the comments below and I’ll do my best help you out =)
Open your updated slideshow in a browser (ensuring there is no #slide-{num}) on
the end of your URL) and wait… See it sliding?…
Great! Now you can click the tabs and watch it slide a little quicker.

Step 5: Highlighting the active tab

So, we’ve got it working but what’s this $slideshow.activateTab()
method that we added? Well it isn’t entirely necessary since the jQuery Cycle
plugin already adds an .activeSlide class to the active navigation
link for you, however, I like to give a little more control over my navigations so
this method just adds an .on class to the parent <li>
of the active link.
With this in place, you can add the following CSS to the end of our
slideshow.css stylesheet to highlight the active tab:
  1. #slideshow .slides-nav li.on,  
  2. #slideshow .slides-nav li.on a {  
  3. background-color#eee;}  
  4.   
  5. #slideshow .slides-nav li.on a {  
  6. positionrelative;  
  7. top: -4px;}  
When you preview, you’ll probably notice that the first tab isn’t highlighted on
page load…this is easy to fix…just use jQuery to add a .js
class to the <body> tag as shown below:
  1. $(function() {  
  2.     // add a 'js' class to the body  
  3.     $('body').addClass('js');  
  4.       
  5.     // initialise the slideshow when the DOM is ready  
  6.     $slideshow.init();  
  7. });      
Then prepend the CSS we just added with the new .js class:
  1. .js #slideshow .slides-nav li.on,  
  2. .js #slideshow .slides-nav li.on a {  
  3. background-color#eee;}  
  4.   
  5. .js #slideshow .slides-nav li.on a {  
  6. positionrelative;  
  7. top: -4px;}  
This means the highlighted buttons will only be styled if the user has javascript
enabled and then we hard code the .on class for the first tab in
the slideshow navigation:
  1. <ul class="slides-nav">  
  2.     <li class="on"><a href="#slide-one">Slide one</a></li>  
  3.     <li><a href="#slide-two">Slide two</a></li>  
  4.     <li><a href="#slide-three">Slide three</a></li>  
  5. </ul>  
…and voila! Try disabling/enabling JavaScript and refreshing the
slideshow to make sure everything still works and we’re done!
Javascript Off

    below the jquery library script tag. view plaincopy to clipboardprint? We’ll now create the slideshow.js file mentioned above and save it in the ‘js’ directory with the following code: view plaincopy to clipboardprint? $slideshow = { context: false, tabs: false, timeout: 1000, // time before next slide appears (in ms) slideSpeed: 1000, // time it takes to slide in each slide (in ms) tabSpeed: 300, // time it takes to slide in each slide (in ms) when clicking through tabs fx: 'scrollLeft', // the slide effect to use init: function() { // set the context to help speed up selectors/improve performance this.context = $('#slideshow'); // set tabs to current hard coded navigation items this.tabs = $('ul.slides-nav li', this.context); // remove hard coded navigation items from DOM // because they aren't hooked up to jQuery cycle this.tabs.remove(); // prepare slideshow and jQuery cycle tabs this.prepareSlideshow(); }, prepareSlideshow: function() { // initialise the jquery cycle plugin - // for information on the options set below go to: // http://malsup.com/jquery/cycle/options.html $("div.slides > ul", $slideshow.context).cycle({ fx: $slideshow.fx, timeout: $slideshow.timeout, speed: $slideshow.slideSpeed, fastOnEvent: $slideshow.tabSpeed, pager: $("ul.slides-nav", $slideshow.context), pagerAnchorBuilder: $slideshow.prepareTabs, before: $slideshow.activateTab, pauseOnPagerHover: true, pause: true }); }, prepareTabs: function(i, slide) { // return markup from hardcoded tabs for use as jQuery cycle tabs // (attaches necessary jQuery cycle events to tabs) return $slideshow.tabs.eq(i); }, activateTab: function(currentSlide, nextSlide) { // get the active tab var activeTab = $('a[href="#' + nextSlide.id + '"]', $slideshow.context); // if there is an active tab if(activeTab.length) { // remove active styling from all other tabs $slideshow.tabs.removeClass('on'); // add active styling to active button activeTab.parent().addClass('on'); } } }; $(function() { // initialise the slideshow when the DOM is ready $slideshow.init(); }); NOTE: To keep this tutorial short, I won’t explain everything in this new javascript file but if you have any questions, feel free to ask in the comments below and I’ll do my best help you out =) Open your updated slideshow in a browser (ensuring there is no #slide-{num}) on the end of your URL) and wait… See it sliding?… Great! Now you can click the tabs and watch it slide a little quicker. Step 5: Highlighting the active tab So, we’ve got it working but what’s this $slideshow.activateTab() method that we added? Well it isn’t entirely necessary since the jQuery Cycle plugin already adds an .activeSlide class to the active navigation link for you, however, I like to give a little more control over my navigations so this method just adds an .on class to the parent
  • of the active link. With this in place, you can add the following CSS to the end of our slideshow.css stylesheet to highlight the active tab: view plaincopy to clipboardprint? #slideshow .slides-nav li.on, #slideshow .slides-nav li.on a { background-color: #eee;} #slideshow .slides-nav li.on a { position: relative; top: -4px;} When you preview, you’ll probably notice that the first tab isn’t highlighted on page load…this is easy to fix…just use jQuery to add a .js class to the tag as shown below: view plaincopy to clipboardprint? $(function() { // add a 'js' class to the body $('body').addClass('js'); // initialise the slideshow when the DOM is ready $slideshow.init(); }); Then prepend the CSS we just added with the new .js class: view plaincopy to clipboardprint? .js #slideshow .slides-nav li.on, .js #slideshow .slides-nav li.on a { background-color: #eee;} .js #slideshow .slides-nav li.on a { position: relative; top: -4px;} This means the highlighted buttons will only be styled if the user has javascript enabled and then we hard code the .on class for the first tab in the slideshow navigation: view plaincopy to clipboardprint? …and voila! Try disabling/enabling JavaScript and refreshing the slideshow to make sure everything still works and we’re done!

  • Final Product
    Read more ...