Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Create a Simple Slideshow Using MooTools, Part II: Controls and Events

22 Responses »

Christina Ricci

Last week we created a very simple MooTools slideshow script. The script was very primitive: no events and no next/previous controls -- just cross-fading between images. This tutorial will take the previous slideshow script a step further by:

  • Adding "Next" and "Previous" controls.
  • Adding a "Table of Contents" so the user may click to any image.
  • Pausing the slideshow when the user places their mouse in the container; resuming the slideshow when the use mouses out.

Obviously our MooTools JavaScript code is going to change quite a bit so be prepared to (mostly) restructure the previous post's JavaScript code.

The HTML

<div id="slideshow-container">
	<img src="slideshow/cricci1.jpg" alt="Christina Ricci" />
	<img src="slideshow/cricci2.jpg" alt="Christina Ricci" />
	<img src="slideshow/cricci3.jpg" alt="Christina Ricci" />
	<img src="slideshow/cricci4.jpg" alt="Christina Ricci" />
	<img src="slideshow/cricci5.jpg" alt="Christina Ricci" />
</div>

Nothing has changed from the previous post. Just images of Christina Ricci which will set your heart ablaze.

The CSS

#slideshow-container	{ width:512px; height:384px; position:relative; }
#slideshow-container img { width:512px; height:384px; display:block; position:absolute; top:0; left:0; z-index:1; }
.toc					{ position:absolute; left:0; bottom:20px; z-index:2; display:block; width:20px; background:#6D84B4; color:#fff; text-align:center; padding:3px; text-decoration:none; }
.toc-active				{ background:#fff; color:#6D84B4; }
#next					{ position:absolute; bottom:20px; right:20px; z-index:2; display:block; width:20px; background:#6D84B4; color:#fff; text-align:center; padding:3px; text-decoration:none; }
#previous				{ position:absolute; bottom:20px; right:60px; z-index:2; display:block; width:20px; background:#6D84B4; color:#fff; text-align:center; padding:3px; text-decoration:none; }

We've added the toc and toc-active CSS classes. The toc-classed items will be absolutely position at the bottom of the container. We'll calculate the left value of each item with MooTools as we don't want them to overlap. We've also defined CSS rules for the Next and Previous buttons we will generate. Feel free to style the TOC items and buttons any way you'd like.

The MooTools JavaScript

window.addEvent('domready',function() {
	/* settings */
	var showDuration = 3000;
	var container = $('slideshow-container');
	var images = container.getElements('img');
	var currentIndex = 0;
	var interval;
	var toc = [];
	var tocWidth = 20;
	var tocActive = 'toc-active';
	
	/* new: starts the show */
	var start = function() { interval = show.periodical(showDuration); };
	var stop = function() { $clear(interval); };
	/* worker */
	var show = function(to) {
		images[currentIndex].fade('out');
		toc[currentIndex].removeClass(tocActive);
		images[currentIndex = ($defined(to) ? to : (currentIndex < images.length - 1 ? currentIndex+1 : 0))].fade('in');
		toc[currentIndex].addClass(tocActive);
	};
	
	/* new: control: table of contents */
	images.each(function(img,i){
		toc.push(new Element('a',{
			text: i+1,
			href: '#',
			'class': 'toc' + (i == 0 ? ' ' + tocActive : ''),
			events: {
				click: function(e) {
					if(e) e.stop();
					stop();
					show(i);
				}
			},
			styles: {
				left: ((i + 1) * (tocWidth + 10))
			}
		}).inject(container));
		if(i > 0) { img.set('opacity',0); }
	});
	
	/* new: control: next and previous */
	var next = new Element('a',{
		href: '#',
		id: 'next',
		text: '>>',
		events: {
			click: function(e) {
				if(e) e.stop();
				stop(); show();
			}
		}
	}).inject(container);
	var previous = new Element('a',{
		href: '#',
		id: 'previous',
		text: '<<',
		events: {
			click: function(e) {
				if(e) e.stop();
				stop(); show(currentIndex != 0 ? currentIndex -1 : images.length-1);
			}
		}
	}).inject(container);
	
	/* new: control: start/stop on mouseover/mouseout */
	container.addEvents({
		mouseenter: function() { stop(); },
		mouseleave: function() { start(); }
	});
	
	/* start once the page is finished loading */
	window.addEvent('load',function(){
		start();
	});
});

I told you it changed quite a bit, didn't I? Here's what I added:

  • I created start, stop, and show functions which do exactly as they're named.
  • Injected table of contents links based upon the number of elements in the slideshow. Each TOC link has a click event which skips to the corresponding slide.
  • Created next and previous links to move forward and backward in the show.
  • Added mouseenter and mouseleave events to stop and start the show when the user triggers each event.

The added code blocks were very simple to add; taking them one at a time kept creating these enhancements quick.

What's Next?

The next step will be transforming the above MooTools JavaScript code into a class. Class-ifying the code will make it cleaner and more organized.

Discussion

  1. December 28, 2009 @ 10:02 am

    Nice post. Looking forward to part 3. Thanks David.

  2. braxo
    December 28, 2009 @ 10:09 am

    In your javascript, line 19, it seems a bit unnecessary to have it so complicated.

    I would argue, for sake of your readers having to re-read that line 5 times to get the gist of its purpose, to break it apart just for readability reasons. Especially because it’s posted in a tutorial.

    I have nothing wrong with ternary operator, I use them myself (and it seems I do more and more with everything I write). But you also included assignments and even nested another ternary in it!

    Maybe instead of removing it or changing it, provide a paragraph describing what that line does. This way your more advanced audience can still see a challenging line of javascript code, but it will also help your more novice readers.

  3. December 29, 2009 @ 5:26 am

    Hi David,

    Nice post, ty.

    I’ve changed it a little: http://gtwebdesignnl/slider/slidertesthtml

    now i can use it for text too.

  4. December 29, 2009 @ 5:27 am
  5. December 29, 2009 @ 7:14 pm

    Nice script… I am about to try it out anyway. I have previous ways of doing ma slide doe but just wanna try out this from mo tools.

  6. ahmed
    December 29, 2009 @ 7:33 pm

    Y0 David, how about having html/div instead of images for the slider, you think it would work?

  7. December 29, 2009 @ 8:13 pm

    @Ahmed: Yes, absolutely!

  8. ahmed
    December 30, 2009 @ 11:10 am

    @David Walsh: Lovely, would you please share a code that uses divs instead of images? I’ve been looking for this for a “while”

  9. December 30, 2009 @ 7:30 pm

    Just what I want. Thank you!

  10. January 2, 2010 @ 5:14 pm

    Thanks as always David!

  11. January 8, 2010 @ 4:13 am

    Just implemented this for a client. Soooo easy! Thanks a million David!

  12. yann
    January 13, 2010 @ 6:33 am

    Hello,

    thanks for this !

    i just need to have a fade more slowly, i try more things like {duration: 5000}, but i can’t make it…

    Can you help me ?

  13. February 24, 2010 @ 4:53 pm

    Hey David,

    Great tutorials! Your site has been very helpful for me.

    I’m trying to use multiple instances of this on one page but it doesn’t seem to work – is this possible, and if so how would I go about making it work?

    Thanks!

  14. rochelle alder
    February 25, 2010 @ 5:41 pm

    I get scripting errors in ie tester. “object expected” which happens on the mouseenter event. In firefox it states undefined object.how do you “correctly” define an object?

  15. March 1, 2010 @ 7:55 am

    This is a great script and very easy to follow instructions. Thanks very much. One thing I am struggling with is to make each slide last longer. Is there a way to do this with the code above? I have looked at the next lesson and although another comment in the thread says that part three includes slide duration, I can’t see how to edit it. Your help would be most appreciated. :-)

  16. rochelle alder
    March 2, 2010 @ 12:21 am

    var showDuration = 3000; is the value you would change. 3000 is 3 seconds. If you want it longer, change 3000 to 8000 to make the transition happen after 8 seconds. Play around with it to suit.

  17. March 2, 2010 @ 3:45 am

    Thanks Rochelle. That should have been very obvious. How stupid of me!

  18. March 6, 2010 @ 7:42 am

    I love that users can control the slideshow.

    I’m new with Mootools but I attracted to it with its lightweightness and hopefully can use this app in the future.

    Good job.

  19. rochelle alder
    March 7, 2010 @ 8:46 pm

    OK so I figured out my problem. I didn’t want the slideshow effect happening with the main image so I commented out the start variable. That resulted in an ‘object not defined’ error.

    So if your variable is not there, but is used within the code, you can expect to get the error in IE but is ignored and runs as it should in firefox although the furebug testing console will tell you there’s an error.

    Thanks David for a great piece of elegant code. Me likey!

  20. bob tipping
    May 6, 2010 @ 7:35 am

    Great script, but no longer works properly with mootools-1.2.4, specifically mouseenter event. It probably requires a very simple change, but I am an absolute beginner and any advice would be greatly appreciated.

  21. bob tipping
    May 6, 2010 @ 7:57 am

    OOps, please disregard my last comment, I had left firebug running by mistake, the script works great with mootools-1.2.4.

  22. June 30, 2010 @ 6:32 am

    Hey David,

    Could the mootools here be tweaked to use a slide transition as opposed to fading?

    Cheers.

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!