The menu at left appears and acts very much like the Explorer menu on Windows
machines. Clicking on an item loads an associated link. Clicking on a folder
will also toggle it open or close it, revealing or hiding a submenu. To close
all the folders, you can click on the root at top.
Some of the features:
Using the Script
This section describes how to set up and create your own tree menu.
The main file defines the frameset and contains all the code. Below is a list of all the files used and their purpose:
Setting Up the Menu
To create your menu, you need to build your own version of myMenu.js. Before you start defining the menu itself, you need to set some global variables:
All the above variables should be defined and set with a value. There are no defaults so leaving any out may cause the menu to fail. Here's a look at the values used for the menu at left:
var treeMenu = new TreeMenu(); var treeMenuName = "myMenu_1.0"; var treeMenuDays = 7; var treeMenuFrame = "menuFrame"; var treeMenuImgDir = "graphics/"; var treeMenuBackground = ""; var treeMenuBgColor = "#ffffff"; var treeMenuFgColor = "#000000"; var treeMenuHiBg = "#008080"; var treeMenuHiFg = "#ffffff"; var treeMenuFont = "MS Sans Serif,Arial,Helvetica"; var treeMenuFontSize = 1; var treeMenuRoot = "Site Menu"; var treeMenuFolders = 0; var treeMenuAltText = true;
Defining the Menu
First, define the top-level menu using the treeMenu global variable:
var treeMenu = new TreeMenu();
Now create some items for it by defining some TreeMenuItem() objects. You specify one to four arguments for an item. The first is the text used in the menu display. The rest apply to the link for the item. They are:
Then you use the addItem method to attach an item to a menu. Here is the code to define and add the main menu items:
The items will be displayed in the order they are added. The first three items here will be submenus, so only the text is given (you could define a link for them as well, but in this case we won't). For links you can leave off the icon value if you wish to use the default images.
We can then reference each item in this menu using the .items array, where treeMenu.items is 'Active Server Pages', treeMenu.items is 'Dynamic HTML', etc.
Defining and Attaching Submenus
We create submenus just like the main menu, using new variables. Here we'll create the 'Active Server Pages' submenu:
var asp = new TreeMenu(); asp.addItem(new TreeMenuItem("Code Examples")); asp.addItem(new TreeMenuItem("Sites"));
Now, to attach this submenu to the main menu, we first reference the main menu item we want to attach it to and use .makeSubmenu() passing the submenu variable as the argument:
This makes the first item in treeMenu a submenu which contains all the items defined in asp.
Each of the items on the 'asp' submenu is also a submenu so for each we create a new TreeMenu, add items to it and then attach it to the appropriate item in the asp submenu.
// Define ASP code examples submenu and // attach to first item of ASP submenu. var asp_ex = new TreeMenu(); asp_ex.addItem(...); asp_ex.addItem(...); ... asp.items.makeSubmenu(asp_ex); // Define ASP sites submenu and attach // to second item of ASP submenu. var asp_sites = new TreeMenu(); asp_sites.addItem(...); asp_sites.addItem(...); ... asp.items.makeSubmenu(asp_sites);
The creation of the DHTML submenus is similar.
Now for the 'Java Applets' submenu we add some items and attach it to the main menu. It has no submenus of it's own so this is all we need to do with it.
var java = new TreeMenu(); java.addItem(...); java.addItem(...); ... // Attach to second item of main menu. treeMenu.items.makeSubmenu(java);
For your own menus, you can define as many items as you want in each menu and you can nest submenus as deep as you want.
You can also change the graphics and icons used for each of the menu parts, see the list of images at the bottom of the page.
Tip: When you update a menu definition, change the value of treeMenuName as well. This will force the script to start create new cookies for the menu data. Otherwise, the old cookie values may be used and this can cause the menu to not work properly.
How it Works
The script defines two objects. One representing an individual menu and another representing an individual item. An item can itself be a menu, allowing for a hierarchial tree structure to be built.
The TreeMenu and TreeMenuItem Objects
The TreeMenu object consists simply of an array used for storing items. It has one method, addItem(), for adding a menu item to this list.
The TreeMenuItem object contains variables to store the item's display text, icon image source (if specified) and data for it's associated link (if any). It also has a pointer which can be set to a TreeMenu object if it is to be a folder. The makeSubmenu() method is used to assign this pointer. It also has an index variable which relates it to the proper value in the menu state cookie (see below) so we can track which folder items are open and which are closed.
Using these, the menu is built when the top-level page is first loaded, creating a hierarchical structure in the global treeMenu variable.
Menu State Data
One cookie is used to track which folders in the menu are open and which are closed. Every item has a boolean value associated with it in this cookie. The values are read in just before the menu is drawn and the values are updated every time the user clicks on an item.
A separate cookie is used to keep track of which item was last clicked, allowing it to be highlighted when drawn. It is also used to determine how far the window needs to be scrolled if that item falls outside of the menu frame's viewable region.
Note that if you update your menu, you should also change the value of treeMenuName so that new cookies will be created from scratch and the old cookie values won't conflict with the new menu structure.
If the user's browser does not support cookies, or if they have been disabled, the menu state will be lost when the user exits the page.
Drawing the Menu
The file treeMenu.html uses the onload event in the <body> tag to call the treeMenuDisplay() function located in the parent file. This function rewrites HTML code of the menu frame to build the menu display based on the current menu state. This new HTML also includes an onload call to run the treeMenuScroll() function, which will scroll the page if necessary for the selected item to be in view.
treeMenuDisplay() works as follows. First, it fetches the cookie data so we will know which folders are to be open and which item was selected last. Then some global variables are set to track where we are in the menu hierarchy and help with the graphics placement.
Then the menu frame document is cleared using the document.open() method. This allows it to completely rewrite the HTML code of the frame. It generates the proper HTML tags to define style sheets and set the page colors and background, if any. It also adds a call to treeMenuScroll() in the onload event of the body tag.
Then, we start the display with a <table> tag. The first row just contains the root icon and text. Each following row will contain a menu item.
Here, the recursive nature of the tree menu objects is what makes the display drawing work. We make a call to treeMenuListItems() passing it the top level menu (the treeMenu variable). When it returns, all the items will have been drawn and we just finish with the closing </table> tag.
treeMenuListItems() is very simple, it just takes the given menu and loops thru each item making a call to treeMenuDisplayItem() to write it out. It also passes a flag to indicate whether the item being passed is the last one in the menu or not so the proper 'tee' or 'corner' graphic can be used.
treeMenuDisplayItem() is the workhorse. It writes out the proper images and text for the given item as a table row. Some global variables are used to track how far to indent the item and what images are needed to create the tree layout. Then, based on the properties of the menu item, it displays the proper icon (folder, file icon, custom icon, etc.) and it's text.
If an item happens to be a submenu it checks the cookie data to determine if it should be expanded or not. If so, it makes a recursive call to treeMenuListItems() passing it the item's submenu.
In this function, we also update the global scrolling values if the given item is the selected one.
Once the menu is finally drawn, some closing tags are output and the menu frame will now reflect the proper menu view.
Making the Menu Interactive
Each item is written as a hypertext link with a call to treeMenuClick() that will cause a redisplay of the menu if the item is clicked. The function is passed the item's index value, so we can update the cookie data and a couple of boolean flags letting it know if the item links to another page and if it is a folder.
The function updates the cookie values, toggling the folder open or closed if it's a submenu and marking the item as the selected one. It then makes a call to treeMenuDisplay() which results in an updated display of the menu.
For the menu root, we call treeMenuRootClick() instead which simply deletes the cookies and redraws the menu frame. This causes it to start with all folders closed and no item selected.
The source for each file can be viewed using these links:
The images for the menu tree are shown below, all are 18x18 pixels in size:
You can also download treeMenu.zip (17K) which contains all the above files.