User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Web Development category of DaniWeb, a massive community of 374,048 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,919 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Web Development advertiser:
Jul 11th, 2006, 1:54 pm
The little comment boxes on Digg are nicely done, allowing you to expand or collapse them with a nice little JavaScript transition.

This is an example of how you can do it. It is also licensed under the "I don't care" license, meaning do whatever you want.

I have been told it functions in Safari, and have personally tested it in Firefox, Opera and IE 6.

The last function that returns all elements with a specific css class isn't mine, so make sure you leave the authors' copyright notice in or rewrite it or whatever.

Enjoy.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Sliding divs - Digg Style</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
<style type="text/css">
* { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000; margin: 0px; padding: 0px; }
body { padding: 20px; }

.slidey { margin-bottom: 10px; }
.slidey .title { background-color: #CCC; } 
/* the only noteworthy thing here is the overflow is hidden, 
it's really a sleight-of-hand kind of thing, we're playing
with the height and that makes it 'slide' */
.slidey .slideblock { overflow: hidden; background-color: #DDD; padding: 2px; font-size: 10px; } 
</style>
<script type="text/javascript">

// our global vars
var heightnow;
var targetheight;
var block;
var slideinterval;
var divheights = new Array();

// the delay between the slide in/out, and a little inertia
var inertiabase = 1;
var inertiainc = 1;
var slideintervalinc = 50;
var inertiabaseoriginal = inertiabase;

window.onload = function()
{
	// detect whether the user has ie or not, how we get the height is different 
	var useragent = navigator.userAgent.toLowerCase();
	var ie = ((useragent.indexOf('msie') != -1) && (useragent.indexOf('opera') == -1) && (useragent.indexOf('webtv') == -1));
	var divs = getElementsByClassName(document, "div", "slideblock");

	for(var i=0; i<divs.length; i++)
	{
		// get the original height
		var baseheight = (ie) ? divs[i].offsetHeight + "px" : document.defaultView.getComputedStyle(divs[i], null).getPropertyValue('height', null);

		// explicitly display it (optional, you could use cookies to toggle whether to display it or not)
		divs[i].style.display = "block";

		// "save" our div height, because once it's display is set to none we can't get the original height again
		var d = new div();
		d.el = divs[i];
		d.ht = baseheight.substring(0, baseheight.indexOf("p"));

		// store our saved versoin
		divheights[i] = d;		
	}
}

// this is one of our divs, it just has a DOM reference to the element and the original height
function div(_el, _ht)
{
	this.el = _el;
	this.ht = _ht;
}

function toggle(t)
{
	// reset our inertia base and interval
	inertiabase = inertiabaseoriginal;
	clearInterval(slideinterval);

	// get our block
	block = t.parentNode.nextSibling;

	// for mozilla, it doesn't like whitespace between elements
	if(block.className == undefined)
		block = t.parentNode.nextSibling.nextSibling;

	if(block.style.display == "none")
	{
		// link text
		t.innerHTML = "Hide";

		block.style.display = "block";
		block.style.height = "1px";

		// our goal and current height
		targetheight = divheight(block);
		heightnow = 1;

		// our interval
		slideinterval = setInterval(slideout, slideintervalinc);
	}
	else
	{
		// linkstext
		t.innerHTML = "Show";

		// our goal and current height
		targetheight = 1;
		heightnow = divheight(block);

		// our interval
		slideinterval = setInterval(slidein, slideintervalinc);
	}
}

// this is our slidein function the interval uses, it keeps subtracting
// from the height till it's 1px then it hides it
function slidein()
{
	if(heightnow > targetheight)
	{
		// reduce the height by intertiabase * inertiainc
		heightnow -= inertiabase;

		// increase the intertiabase by the amount to keep it changing
		inertiabase += inertiainc;

		// it's possible to exceed the height we want so we use a ternary - (condition) ? when true : when false;
		block.style.height = (heightnow > 1) ? heightnow + "px" : targetheight + "px";
	}
	else
	{
		// finished, so hide the div properly and kill the interval
		clearInterval(slideinterval);
		block.style.display = "none";
	}
}

// this is the function our slideout interval uses, it keeps adding
// to the height till it's fully displayed
function slideout()
{
	if(heightnow < targetheight)
	{
		// increases the height by the inertia stuff
		heightnow += inertiabase;

		// increase the inertia stuff
		inertiabase += inertiainc;

		// it's possible to exceed the height we want so we use a ternary - (condition) ? when true : when false;
		block.style.height = (heightnow < targetheight) ? heightnow + "px" : targetheight + "px";
		
	}
	else
	{
		// finished, so make sure the height is what it's meant to be (inertia can make it off a little)
		// then kill the interval
		clearInterval(slideinterval);
		block.style.height = targetheight + "px";
	}
}

// returns the height of the div from our array of such things
function divheight(d)
{
	for(var i=0; i<divheights.length; i++)
	{
		if(divheights[i].el == d)
		{
			return divheights[i].ht;
		}
	}
}

/*
	the getElementsByClassName function I pilfered from this guy.  It's
	a useful function that'll return any/all tags with a specific css class.

		Written by Jonathan Snook, http://www.snook.ca/jonathan
		Add-ons by Robert Nyman, http://www.robertnyman.com
*/
function getElementsByClassName(oElm, strTagName, strClassName)
{
	// first it gets all of the specified tags
    var arrElements = (strTagName == "*" && document.all) ? document.all : oElm.getElementsByTagName(strTagName);
    
	// then it sets up an array that'll hold the results
	var arrReturnElements = new Array();

	// some regex stuff you don't need to worry about
    strClassName = strClassName.replace(/\-/g, "\\-");

    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;

	// now it iterates through the elements it grabbed above
    for(var i=0; i<arrElements.length; i++)
	{
        oElement = arrElements[i];

		// if the class matches what we're looking for it ads to the results array
        if(oRegExp.test(oElement.className))
		{
            arrReturnElements.push(oElement);
        }   
    }

	// then it kicks the results back to us
    return (arrReturnElements)
}
</script>
<noscript>
</noscript>
</head>
<body>

	<div class="slidey">
		<div class="title">
			<a href="#" onclick="toggle(this);">Hide</a>
		</div>
		<div class="slideblock">
			<p>The contents of the sliding block!</p>
			<p>The contents of the sliding block!</p>
			<p>The contents of the sliding block!</p>
			<p>The contents of the sliding block!</p>
		</div>
	</div>

	<div class="slidey">
		<div class="title">
			<a href="#" onclick="toggle(this);">Hide</a>
		</div>
		<div class="slideblock">
			<p>The contents of the sliding block!</p>
		</div>
	</div>

</body>

</html>
This blog entry was written by ben_. It has received 6,081 views, 5 comments, and 23 linkbacks. 2 voters have rated this entry an average of 4.5 out of 5 stars.
AddThis Social Bookmark Button

Comments (Newest First)
formspiel | Newbie Poster | Jun 18th, 2007
Hi!

I got a little question: How I can change your code that all emements are closed at the start?

Thanks!
ghostsquad | Newbie Poster | Jun 9th, 2007
is there anyway to do a toggle? in other words, only be able to have one block open at a time? when you open one, close the last one. I could play around with the code for hours, but if someone already knows how to do this, that would be awesome.
ndunn | Newbie Poster | Mar 5th, 2007
Hi Ben

If you had a whole lot of items that you wanted to expand from one "Expand all" link, how would you do it?

Thanks
Nathan
apogee | Unverified User | Jan 17th, 2007
DOH

Just ignore me!
apogee | Unverified User | Jan 16th, 2007
Hi

Is it possible to have this script start with all items hidden then click to view?

Thanks


Lee
Post Comment

Only community members can start a blog or comment on blog entries. You must register or log in to contribute.

DaniWeb Web Development Marketplace

Related Blog Entries
Related Forum Threads
All times are GMT -4. The time now is 12:23 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC