Sometimes, We Write Stuff...
Mootools Content Slider With Intervals
To celebrate the official release of MooTools 1.2, I decided to post a quick tutorial on making a timed 'content slider' with the new version. I needed to create one of these for a client this afternoon, so I coded one up from scratch... and I thought it might be useful to someone else needing to do something similar. There may be a better method to accomplish this, so if you have one please share with us!
Step One - Grab the New MooTools!
This requires the new official version of MooTools (1.2), which you can grab here: www.mootools.net . You'll notice that instead of one 'download builder' page, there are now two separate downloads. Grab the entire core, and then make sure you grab at least the Fx.Elements plug-in on the 'More Builder' page. (Note: I've included this in the download at the end of the post, but I recommend you build your own version for your project usage elsewhere.)
Step Two - The XHTML
Basically, we just need to make a 'container' div and then inside it we will put the elements we want to display on an interval. I will be using div tags for this – mainly to eliminate any confusion – but obviously you can use whatever fits your needs.
<div id="items_container">
<div class="first_item slide_item">
<h3>Title One</h3>
<p>This is some text that I'm using in the first/initial element.</p>
</div>
<div class="slide_item">
<h3>Title Two</h3>
<p>And here is a bit of text for the second item.</p>
</div>
<div class="slide_item">
<h3>Title Three</h3>
<p>Here is some more amazingly creative filler text. Are you impressed?</p>
</div>
</div>
Step Three - The CSS
For the CSS part of this, we just need to apply a little styling that makes the 'container' div act like a mask. This is easily accomplished by using two attributes together, the overflow attribute and the position attribute.
#items_container {
width: 500px;
height: 200px;
overflow: hidden;
position: absolute; /* this could also be set as 'relative', too */
left: 50px;
top: 80px;
background-color:#CC9933;
}
div.slide_item {
width: 500px;
height: 190px;
position: absolute;
left: 500px;
top: 5px;
background-color:#E2C78D;
}
div.first_item {
left: 0;
}
div.slide_item h3 {
padding: 10px;
font-size: 16px;
line-height: 20px;
font-weight: normal;
color: #6e6c19;
}
div.slide_item p {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
padding: 10px;
}
Step Four - The MooTools
I'm going to break this down into 3 parts: configuration, initialization, and execution.
For the configuration we just establish a couple of variables for setting the speed of things, and then get the elements that we want to slide into an array.
var slideTimer = 5000; //time between slides (1 second = 1000), a.k.a. the interval duration
var transitionTime = 1250; //transition time (1 second = 1000)
var items = $$('.slide_item'); //Get array of elements for sliding
For the initialization, we want to strip out the 'first_item' class on the first element and also set the element positions/opacity for all elements. (Note: The only reason for the 'first_item' class is so that a visitor with javascript disabled will still see something.) This is a super basic initiazation... you could do lots of things here besides initializing positions/opacities.
items.each(function(element, index) {
//since the viewer obviously has javascript on, we can remove the 'first_item' class
if(index == 0){
element.removeClass('first_item');
element.setStyle('left', "0");
}
else{
element.setStyle('left', "500");
element.setStyle('opacity', "0");
}
});
And here is the actual 'slide' code. Take special note of the very last line, which sets the function up to be called on an interval.
var slideFunction = new function() {
var numItems = items.length; //get number of slider items
var itemNum = 0; //initialize a variable to hold the current slide index
var slideIt = function(){
//get item to slide out
var curItem = items[itemNum];
//change index
if(itemNum < (numItems - 1)){
itemNum++;
}
else{
itemNum = 0;
}
//now get item to slide in using new index
var newItem = items[itemNum];
//set up our animation stylings for out and in motions (note: Fx.Styles does NOT exist in moo 1.2, so we must use Fx.Morph or Fx.Tween)
var item_in = new Fx.Morph(newItem, {
duration: transitionTime,
transition: Fx.Transitions.Quad.easeInOut,
wait:false
});
var item_out = new Fx.Morph(curItem, {
duration: transitionTime,
transition: Fx.Transitions.Quad.easeInOut,
wait:false
});
//we will set a beginning value here
//this is so that it gives the illusion of continuous motion from one direction, even after the first cycle of items
item_in.start({
'left': [500, 0],
'opacity':[0,1]
});
//no beginning values needed, since we always want to push the old item out to the left
item_out.start({
'left': '-500',
'opacity':[0]
});
};
//call the function, periodically (note: the interval period is defined at the top of this file)
slideIt.periodical(slideTimer, this);
}
Conclusion
As you can see, this is mainly an abstract tutorial without a lot of 'style' – but there are loads of potential uses for this type of thing. (For example: Show your latest blog posts in a cramped area, show a list of product features/highlights over a product, cycle ads, etc.) Hopefully, you are having an "ah hah!" moment at this point. Thanks for reading, and please leave a comment if you have questions or suggestions!
Download/Demo
+ Comments
Hi Aavan, that should be fairly easy to accomplish. I'll try to get an example of that up tonight or sometime tommorow, ok? (It's a crazy Monday over here, otherwise I'd do it this afternoon!)
Hi George, the updated version with controls is available in the next post.
hi, it's a very nice scroller...do it only work with mootools 1.2 or can i use it with 1.11 as well? thanks
ciao, i'm tring to put this script in a mootools class, but somehow is not working... the animation for incoming slide seems to work fine, i'm aving troubles with the outgoing one... can you help me? where i'm wrong? this is my class code
var Showcase = new Class({
//implements
Implements: [Options],
inFx: new Array(),
outFx: new Array(),
timer:null,
//options
options: {
slideTimer: 5000, //time between slides (1 second = 1000), a.k.a. the interval duration
transitionTime: 1250, //transition time (1 second = 1000)
items: null, //Get array of elements for sliding
itemNum: 0
},
//initialization
initialize: function(options) {
//set options
this.setOptions(options);
this.options.items.each(function(v, k){
this.inFx[k] = new Fx.Morph(v, {
duration: this.options.transitionTime,
transition: Fx.Transitions.Quad.easeInOut,
wait:false
});
this.outFx[k] = new Fx.Morph(v, {
duration: this.options.transitionTime,
transition: Fx.Transitions.Quad.easeInOut,
wait:false
});
}, this);
},
//a method that does whatever you want
start: function() {
//call the function, periodically (note: the interval period is defined at the top of this file)
this.timer = this.slideIt.periodical(this.options.slideTimer, this);
},
slideIt: function() {
var numItems = this.options.items.length; //get number of slider items
var curItem = this.options.itemNum;
//change index
if(this.options.itemNum < (numItems - 1)){
this.options.itemNum++;
}
else{
this.options.itemNum = 0;
}
var newItem = this.options.itemNum;
//we will set a beginning value here
//this is so that it gives the illusion of continuous motion from one direction, even after the first cycle of items
this.inFx[curItem].start({
'left': [500, 0],
'opacity':[0,1]
});
//no beginning values needed, since we always want to push the old item out to the left
this.outFx[newItem].start({
'left': '-500',
'opacity':[0]
});
}
});
sorry...the wrong thing in my code is here:
this.inFx[curItem].start({ ‘left’: [500, 0], ‘opacity’:[0,1] });
this.outFx[newItem].start({ ‘left’: ‘-500’, ‘opacity’:[0] });
sould be:
this.inFx[newItem].start({ ‘left’: [500, 0], ‘opacity’:[0,1] });
this.outFx[curItem].start({ ‘left’: ‘-500’, ‘opacity’:[0] });
Very nice job, Null! (I am just now reading both of your comments.)
First, glad you were able to solve the problem! Secondly, thanks for sharing your class – I know a lot of people will find it helpful!
(And I see that something weird happens when posting code in these comments... I'll get that fixed, sorry!)
I would like to know how can I add a hyperlink to control the slide_item on mouse over exemple: after slide 1 enters then slide 2 how can I click in the hyperlink and come back to slide 1? Please I need that, thank you!
@mo and Clavel: You might want to take a look at the more recent 'content slider' posts I've made here. This particular one is the most basic version...
ciao, i'm going on developping my version of your idea... but i'm a bit worried by using the absolute positioning
do you think it could be possible to have the same sliding effect without the absolute positioning, and for it, working on something else instead the left css property ?
Hi Nulll,
I'm pretty sure you could do it with relative positioning as well, but you'll definitely need to use one or the other to perform a 'sliding' effect. I just like using absolute positioning inside of relatively positioned elements, as it gives me full control of placement with any browser/OS combination.
As for using the 'left' property, again - you'll probably need to use that to achieve any style of sliding effect. (You could use 'top' if you wanted a vertical slide...)
I suppose you could also do this type of effect with margins or padding, but I think you'd find issues with certain browsers.
Here's a preview of your comment: