Animated Div Collapsing

A few years ago I was looking for a simple JavaScript to animate the hiding/showing of a div. I came across one that was perfect from harrymaugans.com but the site is currently undergoing a revamp so the original post is no longer there. Anyway the script was perfect but it had one issue, it required that the div’s height be already set and I was working with dynamically populated divs that I wouldn’t know the size of. My original solution was to loop through the divs I was going to hide and set their height to what their height currently was (if that makes sense) before hiding them with display: none;. Anyway I got sidetracked and I felt this solution was inadequate anyway so left it in my test folder. Jump to the present day. I started looking at it again and realised I can grab the original height of the div once it’s display had been changed back to block by the script and it’s height set to 1px ready for the sliding into view. The solution was simply to use scrollHeight which gets the height of a div including any hidden content such as when overflow is set to hidden.

I also added a new function, toggleSlide, which means instead of needing a link to call the slideDown and then one to call the slideUp you can just call toggleSlide and it will either slide it up or down depending on it’s current state.

And so I am offering my version of the script here since I think some people might be in the same boat as me and find my solution useful and also because the original source is no longer available.

/* 
   Originally from http://www.harrymaugans.com/2007/03/06/how-to-create-an-animated-sliding-collapsible-div-with-javascript-and-css/
 
   Update by Carbonize - http://carbonize.co.uk 
   Date: Sun, 10 March 2013 20:15:24 GMT
 
   To use simply use slidedown(objects ID) to slide it down/open or slideup(object ID) to make it slide up/closed
 
   Or simpler yet I have added toggleSlide(object ID) so you can just call one function and it will automatically slide the object 
   up or down depending on it's current situation
 
  Please remember to set the elements overflow to hidden as in overflow: hidden; otherwise it's contents will be visible.
 
  And you might want to add return: false; when you call it to stop the link you are using from doing anything.
*/
var timerlen = 5;
var slideAniLen = 250;
 
var timerID = new Array();
var startTime = new Array();
var obj = new Array();
var endHeight = new Array();
var moving = new Array();
var dir = new Array();
 
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);
}
 
function startslide(objname){
  obj[objname] = document.getElementById(objname);
 
  startTime[objname] = (new Date()).getTime();
 
  if(dir[objname] == "down"){
          obj[objname].style.height = "1px";
  }
 
  obj[objname].style.display = "block";
  endHeight[objname] = parseInt(obj[objname].scrollHeight);
 
  timerID[objname] = setInterval('slidetick(\'' + objname + '\');',timerlen);
}
 
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;
}
 
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;
}
 
function toggleSlide(objname) {
  // Pointless going any further if we are already sliding the object
  if(moving[objname])
          return;
  if (document.getElementById(objname).style.display == 'none') {
    // div is hidden, so let's slide down
    slidedown(objname);
  } else {
    // div is not hidden, so slide up
    slideup(objname);
  }
}

Here’s some example HTML

<a onclick="toggleSlide('myDiv'); return false;" href="somewhere.php">Toggle Div</a>

Leave a Reply

Post Popularity Graphing by Knowledge Ring