CollapseMenu Object

This is a slick little object for making animated collapsable menus for your navigation. It works very well in a totally layer-based page, as well can fully serve as the navigation for a Frames-based website. It's very simplistic, and leaves a lot of stuff open to you as far as the layout of it's contents and operation. Only restriction is that it's not infinitely nestable (can only have one level of sub-blocks). I may build another version with support for that, and also for automatically swapping an image for "twisty" images (like an arrow that flips down when you open a node).

This object can optionally use the Glide Methods for it's animation which really looks great, and is probably the only way you'd want it, but it can also use the standard Slide methods, or just instantly open.

Constructor

CollapseMenu(x,y,width,numBlocks,name)

Example setup:

collapse = new CollapseMenu(50,50,200,5)
collapse.openStyle = 'glide'
collapse.build()

writeCSS(
collapse.css
)

// in init()
collapse.activate()

The writing of the div tags is mostly a manual process in this object. This is how you'd set up the div's for 3 blocks:

<script language="JavaScript">
document.write(collapse.divStart)
</script>

<div id="CollapseMenu0Block0">
<div id="CollapseMenu0Block0Item"></div>
<div id="CollapseMenu0Block0Content">
</div>

<div id="CollapseMenu0Block1">
<div id="CollapseMenu0Block1Item"></div>
<div id="CollapseMenu0Block1Content">
</div>

<div id="CollapseMenu0Block2">
<div id="CollapseMenu0Block2Item"></div>
<div id="CollapseMenu0Block2Content">
</div>

<script language="JavaScript">
document.write(collapse.divEnd)
</script>

Notice a few things:

To open a sub-menu what you'll usually do is have a link inside the "Item" layer that calls the CollapseMenu toggle() method:

collapse.toggle(2) // open/close the 3rd block

That link will serve as the "node", it will always be visible, any content in the "Content" layers will be covered up until you click on the link to toggle it open. So your layers will usually all have this:

<script language="JavaScript">
document.write(collapse.divStart)
</script>

<div id="CollapseMenu0Block0">
<div id="CollapseMenu0Block0Item"><a href="javascript:collapse.toggle(0)">item 0</a></div>
<div id="CollapseMenu0Block0Content">

my content goes here

</div>

<div id="CollapseMenu0Block1">
<div id="CollapseMenu0Block1Item"><a href="javascript:collapse.toggle(1)">item 1</a></div>
<div id="CollapseMenu0Block1Content">

my content goes here

</div>

<div id="CollapseMenu0Block2">
<div id="CollapseMenu0Block2Item"><a href="javascript:collapse.toggle(2)">item 2</a></div>
<div id="CollapseMenu0Block2Content">

my content goes here

</div>

<script language="JavaScript">
document.write(collapse.divEnd)
</script>

After you've got that set up you should be able to activate() the object and it will open your sub-menus as expected.

A tip to help Netscape's display

In Netscape if your list of content is very long it will go past the bottom of the screen. Netscape does not register the height of layers to the document so the default scrollbar in Netscape will not coincide with the height of your CollapseMenu. However, you can account for this by manually setting the height of the document to the height of your CollapseMenu by doing the following after you've activated your object:

if (is.ns) document.height = collapse.lyr.y + collapse.h

That takes the top-location of the collapse and adds it to the height of the collapse (which was calculated automatically for you). You can only set the height of the document once, so you have no choice but to set it to the total height of the menu.

Animation Options

You have 3 choices

You can set this option at any time with either one of:

collapse.openStyle = "glide"
collapse.openStyle = "slide"
collapse.openStyle = "move"

Example: collpasemenu1.html [source] - a simple CollapseMenu example

Example: collpasemenu2.html [source] - a CollapseMenu will links to pages in this tutorial

Properties, Methods, and DynLayers Summary

Property NameDescription
nameholds the name used for all the layers
wthe width of the menu (set manually in constructor)
hthe height of the menu (automatically found after activate())
numBlocksnumber of blocks, same you sent in the constructer - this is read only, you cannot add new blocks dynamically
openStyletype of animation to open with
bgColorbackground for all layers, cannot be transparent because you'll see all content through all the blocks
contentIndentnumber of pixels to indent the content layers
increpetition increment in pixels (for slide) or degrees (for glide)
speedrepetition delay in milliseconds
activeboolean value whether the menu is currently in motion (true means it's opening or closing, false means it's still)
itemTotaltotal height of the "Item" layers
ContentTotaltotal height of the "Content" layers
blocks[]an array holding the information for each block
blocks[i].openboolean whether the block is open or not
blocks[i].itemHeightheight of item for that block
blocks[i].contentHeightheight of content for that block
blocks[i].hitemHeight + contentHeight

Method NameDescription
build()assembles the css and div properties to create the layers needed
activate()assigns all DynLayers and gets relevant information to allow the object to function
toggle(i)opens the block if closed, closes it if open
open(i)opens the block
close(i)closes the block

DynLayer NameDescription
lyrthe top-most layer of the CollapseMenu
blocks[i].lyrlayer for the whole block (contains item and content layers)
blocks[i].itemlyritem layer
blocks[i].contentlyrcontent layer

The onToggle Event

This is called immediately after a particular block has been toggled:

mycollapse.onToggle = new Function("alert('I\ve been toggled')")

CollapseMenu-in-a-Scroll

Yup it works very well. The demo below shows a thorough example including a function to syncronize the height of the Scroll with the height of the CollapseMenu:

// onToggle handler to sync the height of a Scroll with a CollapseMenu
function CollapseSynchScroll() {
	var h = this.itemTotal
	for (var i=0;i<this.numBlocks;i++) {
		if (this.blocks[i].open) {
			h += this.blocks[i].contentHeight
		}
	}
	if (this.scroll.window.contentlyr.y<0 && h<this.scroll.window.screenlyr.h) {
		this.scroll.window.contentlyr.moveTo(null,0)
	}
	this.scroll.activate(this.w,h,false)
}

Example: collpasemenu-scroll.html [source] - a CollapseMenu inside a scroll

Source Code

collapsemenu.js

Home Next Lesson: PushPanel Object
copyright 1998 Dan Steinman