Jump to Table of Contents

Example: Slideshow

This example illustrates how to create a slideshow using paginator to control the slides.

paused...

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>