docs:programming:javascript:sliding_div

Sliding Div

So, expanding on the last tutorial, I’ve coded a small Javascript library that will allow that functionality. It’s not meant to be a mootools or a script.aculo.us replacement… those are far more advanced libraries. This is just a simple, quick bit of code you can apply to your websites to improve the user experience a bit.

In this tutorial, we will create functions to slide DIVs up and down. It supports multiple animations happening simultaneously, as well as a variable animation length. It’s also time-based, rather than increment based, so it’ll animate the same speed on most computers; old computers won’t take 10 minutes for a DIV to slide down.

Click here to see the final product.

First, create a new file on your webserver called motionpack.js - this is where we will store all the javascript functions for the animations, rather than cluttering up the top of the webpage itself, and slowing down it’s load time. In the beginning of that file, let’s first declare some initial variables:

var timerlen = 5;
var slideAniLen = 500;

These are the variables you will change if you want to tweak the speed of the animation on your site. timerlen is how often the Javascript function will run to alter the DIV’s properties (altering height or opacity)… it’s probably best to leave this at 5. Any lower will be slightly smoother, but will require your visitors have a better computer (otherwise it’ll be choppy), and much higher will be choppy on everyone, because it’s not updating enough to look smooth. The next variable, slideAniLen, is how long it should take a DIV to completely slide up or completely slide down. This is in milliseconds, so setting it to 500 means it’ll take half a second to complete the animation effect. This is fairly quick, so some people might want to increase and make it a bit slower.

Now, the next part of the JS file:

var timerID = new Array();
var startTime = new Array();
var obj = new Array();
var endHeight = new Array();
var moving = new Array();
var dir = new Array();

These are some variables we’ll use throughout the code below to keep track of our animations. We use arrays for each object to allow multiple animations to happen simultaneously. We’ll explain where each of these are used later on, but for now, simply paste them into your JS file.

Now we’re getting to the actual functions. These first functions are what we call from our website itself. They essentially serve as the API for this mini-library.

function slidedown(objname){
  if(moving[objname])
    return;
 
  if(document.getElementById(objname).style.display != "none")
    return; // cannot slide down something that is already visible
 
  moving[objname] = true;
  dir[objname] = "down";
  startslide(objname);
}
 
function slideup(objname){
  if(moving[objname])
    return;
 
  if(document.getElementById(objname).style.display == "none")
    return; // cannot slide up something that is already hidden
 
  moving[objname] = true;
  dir[objname] = "up";
  startslide(objname);
}

This code adds the functions to call when requesting a DIV start sliding up or down. Let’s first look at the slideup() function. We pass it a single parameter- the DIV’s id (objname). The first line checks if the moving variable is set to true for that DIV, so we don’t begin animation on one that’s already moving. Once an animation starts, it will finish uninterrupted. If it is moving, on line 3, we return (exit from the function) so no further animation begins. The next line is a sanity checking if-statement. This function is beginning the slide down process of a DIV, and if a DIV’s display attribute is not set to none (not visible), we assume it’s already slid down and visible, so we can exit the function (abort the process), since there’s nothing else for us to do here. If those checks complete without any complications, we’re now ready to begin the sliding process, so we set the moving variable to true (so no other animation can start until we’re done), we set the direction variable to down (so it knows which way to move), and we call the function startslide(), which we’ll get to in a moment. The slideup() function is very similar, except it checks on the 3rd line inside that function to ensure the display property is not set to “none”, so the DIV is not visible, otherwise we have nothing to slide up, and we can abort the start slide process.

Now, I hope you guys are hanging in there, we’re almost through the tricky parts. :)

The next function we’ll throw in the file is the startslide() function mentioned above:

function startslide(objname){
  obj[objname] = document.getElementById(objname);
 
  endHeight[objname] = parseInt(obj[objname].style.height);
  startTime[objname] = (new Date()).getTime();
 
  if(dir[objname] == "down"){
    obj[objname].style.height = "1px";
  }
 
  obj[objname].style.display = "block";
 
  timerID[objname] = setInterval('slidetick(\'' + objname + '\');',timerlen);
}

Okay, the last two functions were for making sure we really want to start the slide, and doing all the initial preparations. This function, startslide(), is where we actually begin the sliding process. We, as always, pass the DIV’s id (objname) that we’re working with as the function’s parameter. On the first line of this function, we set it in the obj[] array, so we can keep track of the id throughout the animation process. The next two lines set the endHeight to the original height (so we know where to start sliding from, or how far down to slide to), and the startTime, so we can keep track of how long this animation has been going on. Following this we have a nice three line if-statement that checks if we’re sliding down, and if we are, resizes the DIV’s height to 1px… a starting point to slide down from. Next it sets the object’s display attribute to “block”, making it visible (redundant if sliding up, but a good just-in-case measure never-the-less). Note: You might want to use “inline” instead of “block”, depending on your circumstances (inline will allow the DIV to have other content to the left and right of it, rather than adding a line break before and after it like block does), just be aware to change the other occurrences of “block” to “inline” if you do this. Finally the last line of the function is where we’ve set the initial timer, which will call the sliding function ever few milliseconds (depending on your settings of timerlen up top), and actually perform the animation itself.

Now, the function the above timer called was slidetick(), which is the next part of our motionpack.js file.

function slidetick(objname){
  var elapsed = (new Date()).getTime() - startTime[objname];
 
  if (elapsed > slideAniLen)
    endSlide(objname)
  else {
    var d =Math.round(elapsed / slideAniLen * endHeight[objname]);
    if(dir[objname] == "up")
      d = endHeight[objname] - d;
 
    obj[objname].style.height = d + "px";
  }
 
  return;
}

This function is what actually does the animation itself. The first line checks how long the animation has been in progress, by subtracting the animation’s start time from the current time. There’s then an if-statement that checks if the animation has exceeded the preset time (at the top of this file) for an animation’s length, and if so, it calls the endSlide() function, which cleans up (discussed below). If the elapsed time is not greater than the max time (the else-statement), it calculates the variable “d”. This calculation takes the ratio of time that’s progressed so far in the animation, and multiplies it by the final height of the DIV, so if half the time has progressed, for example, the variable d will contain half the height. Then it checks the direction, and if we’re sliding up, it alters d to it’s inflection… sliding the opposite direction (three quarters the way through the time would either be three quarters the way down if sliding down, or a quarter of the way from the top, if sliding up). Next we set the DIV’s height to “d” using it’s CSS style.height property.

Now, the last function we’re needing in the motionpack.js file is the endSlide() function:

function endSlide(objname){
  clearInterval(timerID[objname]);
 
  if(dir[objname] == "up")
    obj[objname].style.display = "none";
 
  obj[objname].style.height = endHeight[objname] + "px";
 
  delete(moving[objname]);
  delete(timerID[objname]);
  delete(startTime[objname]);
  delete(endHeight[objname]);
  delete(obj[objname]);
  delete(dir[objname]);
 
  return;
}

This is the function that’s called when the time runs out on an animation. It finishes everything and cleans up. The first line kills the animation timer, so it doesn’t keep trying to slide. The if-statement checks, and if it was sliding up, it hides the DIV by changing it’s display attribute to “none”. It readjusts the DIV’s height to the original height, so future animations will work fine on it. Then finally there are all those delete lines, deleting any array element we created to keep track of the different animations throughout the process. This cleans up a bit to ensure there are no memory leaks (for sites with lots of animations), etc. After this function is completed, the animation process is done.

Now you can save that file, with all the pieces above saved up, and upload it to your webserver.

To download the entire above JS file, you can get it here.

Now, we have our entire mini-library done…. so how do we use it?

First we need to include it in our website. This is done by adding this quick line to your website on every page that you’re using the animation, preferably in the HEAD tag:

<script language="JavaScript" src="motionpack.js"></script>

This code assumes the file you uploaded is named “motionpack.js” and is in the same folder as your website source code itself. Another common practice is to create a folder called js/ and put all your javascript include files there together, and in that case, you’d change the src tag above line to “js/motionpack.js”. Easy.

Now that page of your website has sliding abilities! But how do we use them?

First, let’s create a DIV, like we did with our last collapsible DIV tutorial:

<div id="mydiv" style="display:none; overflow:hidden; height:95px;"><h3>This is a test!<br>Can you see me?</h3></div>

Notice we did make one change though. We added an “overflow: hidden” attribute and “height:95px” to the style property of the DIV. These property MUST be present on all DIVs you use for sliding. If you don’t include the overflow attribute, it’ll look very ugly, with text overlapping on other content and such. If you don’t include a static height here, it won’t know how far to slide, so it won’t work at all. Aside from that, it’s virtually the same. You can put whatever you want inside the div, just be sure to adjust the height accordingly.

The difference is this time our link calls functions from our library above. Here’s an example of what a Slide Down link might look like:

<a href="javascript:;" onmousedown="slidedown('mydiv');">Slide Down</a>

Notice in the onmousedown function we call the slidedown() function from our above library. This will begin the animation and slide the DIV down, until it’s completely visible. You can replace slidedown() with slideup() to do just that, slide the DIV up.

As a challenge to you, try using what you’ve learned in this tutorial and the last to create a toggleSlide() function. It would be a simple if-statement to check if the link’s “display” property, and either slide it up or down, depending on it’s state. We did something very similar in the last tutorial, so try applying that here!

  • docs/programming/javascript/sliding_div.txt
  • Last modified: 2008/08/03 00:25
  • by 127.0.0.1