This example illustrates how to create a slideshow using paginator to control the slides.
Setting Up the Interface
First we need to construct the HTML for the slideshow.
This includes our slides, and controls, as well as a message that is displayed when the slideshow is paused.
If you do not want an automated slideshow, this can be left out.
<div id="spiffySlides"> <ul class="slides"> <li class="active"> <img src="../assets/paginator/images/1.jpg"> </li> <li> <img src="../assets/paginator/images/2.jpg"> </li> <li> <img src="../assets/paginator/images/3.jpg"> </li> <li> <img src="../assets/paginator/images/4.jpg"> </li> <li> <img src="../assets/paginator/images/5.jpg"> </li> </ul> <ul class="controls"> <li class="active"><a href="#slide-1">1</a></li> <li><a href="#slide-2">2</a></li> <li><a href="#slide-3">3</a></li> <li><a href="#slide-4">4</a></li> <li><a href="#slide-5">5</a></li> </ul> <div class="paused">paused...</div> </div>
Now let's jazz it up a bit with some CSS.
<style scoped> #spiffySlides { position: relative; overflow: hidden; display: inline-block; zoom: 1; *display: inline; } /* - S L I D E S - */ #spiffySlides .slides { margin: 0; padding: 0; width: 630px; height: 350px; position: relative; box-shadow: 0 0 3px hsla(250, 40%, 30%, 0.8); } #spiffySlides .slides li { position: absolute; left: 0; top: 0; list-style: none; display: inline; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity 0.3s ease-out; -moz-transition: opacity 0.3s ease-out; -o-transition: opacity 0.3s ease-out; transition: opacity 0.3s ease-out; } #spiffySlides .slides .active { opacity: 1; filter: alpha(opacity=100); -webkit-transition: opacity 0.3s ease-out; -moz-transition: opacity 0.3s ease-out; -o-transition: opacity 0.3s ease-out; transition: opacity 0.3s ease-out; } /* - C O N T R O L S - */ #spiffySlides .controls { width: 630px; text-align: right; margin: 3px 0 0; padding: 8px 0 0; position: relative; z-index: 1; } #spiffySlides .controls li { list-style: none; display: inline; } #spiffySlides .controls a { display: inline-block; zoom: 1; *display: inline; padding: 0 10px; border: solid 1px #CBCBCB; text-decoration: none; line-height: 1.7em; color: #4A4A4A; font-family: arial,san-serif; } #spiffySlides.circles .controls a { text-indent: 100px; overflow: hidden; border-radius: 50%; width: 12px; height: 12px; padding: 0; } #spiffySlides .controls a:hover { background-color: #bfdaff; color: #000; } #spiffySlides .controls .active a, #spiffySlides .controls .active a:hover { background: #2647a0; color: #ffffff; } /* - P A U S E M E S S A G E - */ #spiffySlides .paused { opacity: 0; filter: alpha(opacity=0); bottom: 5px; left: -130px; letter-spacing: 18px; position: absolute; color: #2a2a2a; width: 630px; line-height: 1.8em; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } #spiffySlides:hover .paused { opacity: 1; filter: alpha(opacity=100); left: 30px; letter-spacing: 1px; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } </style>
JavaScript
Setting Up the YUI Instance
Now we need to create our YUI instance and tell it to load the modules.
YUI().use('node', 'paginator', 'event-hover', 'gallery-timer', function (Y) { // code goes here... });
There are only a few modules we need to require:
- node: Allows us to access the elem ents on the page and gives us basic event attachment
- paginator: Gives us the paginator
- event-hover: Let's us track moving the mouse over and out of an element
- gallery-timer: Let's us create a timer to pause and resume when we mouse in and out of the element
If you are not interested having an automated slideshow, you can leave out event-hover
and gallery-timer
.
Defining our variables
var spiffy = Y.one('#spiffySlides'), slides = spiffy.all('.slides li'), controls = spiffy.all('.controls li'), selectedClass = 'active', pg = new Y.Paginator({ itemsPerPage: 1, totalItems: slides.size() });
We start our slide show by saving a reference to the slideshow container, #spiffySlides
. Then we get a reference to all the slides and store them in a Y.NodeList
. Our next variable, controls
, stores a Y.NodeList
of the control elements.
After that we store our string for selected slides and controls. This will make maintenence easier for us later on.
Next, we create a new Y.Paginator
that will display only one item, or "slide", at a time. We use the size()
method of our slides
NodeList to get the total number of items in our paginator.
Binding Paginator's pageChange
Now that we have our variables in place, we need to define what happens when the page number changes in the paginator.
pg.after('pageChange', function (e) { var page = e.newVal; // decrement page since nodeLists are 0 based and // paginator is 1 based page--; // clear anything active slides.removeClass(selectedClass); controls.removeClass(selectedClass); // make the new item active slides.item(page).addClass(selectedClass); controls.item(page).addClass(selectedClass); });
Paginator's first page is always 1, and since a NodeList
's first element is at 0, we need to subtract 1 from the page to give us the proper index in the slides and controls list. (index = page - 1;
)
After we get the proper index, we need to remove any evidence of a preceeding active slide then make the new slide and control active.
Binding clicks on page controls
To define the controls click event, we can delegate on all anchor (<a>
) elements within the .controls
element.
// when we click the control links we want to go to that slide spiffy.delegate('click', function (e) { e.preventDefault(); var control = e.currentTarget; // if it's already active, do nothing if (control.ancestor('li').hasClass(selectedClass)) { return; } pg.set('page', parseInt(control.getHTML(), 10)); }, '.controls a');
First we prevent the default behavior of the anchor element.
Then we check to see if it's active. If it is, we simply return
out of the function to prevent any further action.
If it's not active, we need to get the page number to go to. To do that, we use the number from the element and send it to the paginator. Since Paginator
only takes numbers, we need to parse the string before we set it.
At this point we are done with the slideshow funtionality.
The rest of this walk through will be covering making the slideshow automated.
Automating the Slideshow
Using gallery-timer
, we will create a new Timer
object.
// create a timer to go to the next slide automatically // we use timer to obtain a pause/resume relationship autoPlay = new Y.Timer({ length: 2500, repeatCount: 0}); autoPlay.after('timer', function (e) { if (pg.hasNextPage()) { pg.nextPage(); } else { pg.set('page', 1); } }); // start the autoPlay timer autoPlay.start();
We want the slides to advance every 2.5 seconds, so we set the length to 2500. We make it run continuously by setting repeatCount to zero.
The timer fires a 'timer'
event on every loop. We listen for this event to proceed to the next slide. If there isn't a next slide, we simply go back to the first one.
Pausing the Slideshow
We probably do not want to have the slideshow run while we are trying to interact with the controls, so let's make it pause when we mouse over the whole thing.
// we want to pause when we mouse over the slide show // and resume when we mouse out spiffy.on('hover', function (e) { autoPlay.pause() }, function (e) { autoPlay.resume() });
Using the event-hover
module, we can define the mouse over and mouse out behavior at one time. When we mouse over the slideshow, we pause the timer. When we mouse out of the slideshow, we resume the timer.
The Whole Example
That's it! Now let's put it all together.
<style scoped> #spiffySlides { position: relative; overflow: hidden; display: inline-block; zoom: 1; *display: inline; } /* - S L I D E S - */ #spiffySlides .slides { margin: 0; padding: 0; width: 630px; height: 350px; position: relative; box-shadow: 0 0 3px hsla(250, 40%, 30%, 0.8); } #spiffySlides .slides li { position: absolute; left: 0; top: 0; list-style: none; display: inline; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity 0.3s ease-out; -moz-transition: opacity 0.3s ease-out; -o-transition: opacity 0.3s ease-out; transition: opacity 0.3s ease-out; } #spiffySlides .slides .active { opacity: 1; filter: alpha(opacity=100); -webkit-transition: opacity 0.3s ease-out; -moz-transition: opacity 0.3s ease-out; -o-transition: opacity 0.3s ease-out; transition: opacity 0.3s ease-out; } /* - C O N T R O L S - */ #spiffySlides .controls { width: 630px; text-align: right; margin: 3px 0 0; padding: 8px 0 0; position: relative; z-index: 1; } #spiffySlides .controls li { list-style: none; display: inline; } #spiffySlides .controls a { display: inline-block; zoom: 1; *display: inline; padding: 0 10px; border: solid 1px #CBCBCB; text-decoration: none; line-height: 1.7em; color: #4A4A4A; font-family: arial,san-serif; } #spiffySlides.circles .controls a { text-indent: 100px; overflow: hidden; border-radius: 50%; width: 12px; height: 12px; padding: 0; } #spiffySlides .controls a:hover { background-color: #bfdaff; color: #000; } #spiffySlides .controls .active a, #spiffySlides .controls .active a:hover { background: #2647a0; color: #ffffff; } /* - P A U S E M E S S A G E - */ #spiffySlides .paused { opacity: 0; filter: alpha(opacity=0); bottom: 5px; left: -130px; letter-spacing: 18px; position: absolute; color: #2a2a2a; width: 630px; line-height: 1.8em; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } #spiffySlides:hover .paused { opacity: 1; filter: alpha(opacity=100); left: 30px; letter-spacing: 1px; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } </style> <div id="spiffySlides"> <ul class="slides"> <li class="active"> <img src="../assets/paginator/images/1.jpg"> </li> <li> <img src="../assets/paginator/images/2.jpg"> </li> <li> <img src="../assets/paginator/images/3.jpg"> </li> <li> <img src="../assets/paginator/images/4.jpg"> </li> <li> <img src="../assets/paginator/images/5.jpg"> </li> </ul> <ul class="controls"> <li class="active"><a href="#slide-1">1</a></li> <li><a href="#slide-2">2</a></li> <li><a href="#slide-3">3</a></li> <li><a href="#slide-4">4</a></li> <li><a href="#slide-5">5</a></li> </ul> <div class="paused">paused...</div> </div> <script> YUI().use('node', 'paginator', 'event-hover', 'gallery-timer', function (Y) { var spiffy = Y.one('#spiffySlides'), slides = spiffy.all('.slides li'), controls = spiffy.all('.controls li'), selectedClass = 'active', pg = new Y.Paginator({ itemsPerPage: 1, totalItems: slides.size() }); pg.after('pageChange', function (e) { var page = e.newVal; // decrement page since nodeLists are 0 based and // paginator is 1 based page--; // clear anything active slides.removeClass(selectedClass); controls.removeClass(selectedClass); // make the new item active slides.item(page).addClass(selectedClass); controls.item(page).addClass(selectedClass); }); // when we click the control links we want to go to that slide spiffy.delegate('click', function (e) { e.preventDefault(); var control = e.currentTarget; // if it's already active, do nothing if (control.ancestor('li').hasClass(selectedClass)) { return; } pg.set('page', parseInt(control.getHTML(), 10)); }, '.controls a'); // create a timer to go to the next slide automatically // we use timer to obtain a pause/resume relationship autoPlay = new Y.Timer({ length: 2500, repeatCount: 0}); autoPlay.after('timer', function (e) { if (pg.hasNextPage()) { pg.nextPage(); } else { pg.set('page', 1); } }); // start the autoPlay timer autoPlay.start(); // we want to pause when we mouse over the slide show // and resume when we mouse out spiffy.on('hover', function (e) { autoPlay.pause() }, function (e) { autoPlay.resume() }); }); </script>