Bytes Expert Newtork: Connect with experts in IT / Business | Expert Topics



Search


Go Back   Programmers Resource > Code Section > ASP Articles
User Name
Password


 
 
Thread Tools Search this Thread Rating: Thread Rating: 5 votes, 4.40 average. Display Modes
  #1  
Old 06-11-2003, 02:18 PM
Angelika Angelika is offline
Moderator
 
Join Date: May 2003
Location: NJ
Posts: 125
The Pop-Up Menu (JavaScript)

The Pop-Up Menu Procedure

Creating three style sheet rules
Build the Menu System
Write the Code
Attach the Events
Add Sub-Menus


Creating Style Sheet Rules
Start by creating three style sheet rules: one for the menu bar, one for the menu triggers, and one for the menus themselves. The following style tag includes basic hyperlink rules for the links embedded in the menus:
<style>
.menu a{
color: #000080;
font-weight: bold;
text-decoration: none;
}
.menu a:hover{
color: yellow;
font-weight: bold;
}
.menuBar{
background-color: #9999FF;
position: absolute;
top: 40px;
left: 0;
height: 15;
z-index: 1;
padding: 4px;
}
.menuTrigger{
font: 10pt Verdana, sans-serif;
color: #000099;
font-weight: bold;
background-color: #9999FF;
position: absolute;
top: 40px;
padding: 4px;
width: 100;
height: 15;
z-index: 2;
cursor: pointer;
cursor: hand;

}
.menu{
font: 8pt Verdana, sans-serif;
color: #000080;
font-weight: bold;
background-color: #CCCCFF;
position: absolute;
top: 60px;
padding: 4px;
width: 100;
visibility: hidden;
z-index: 2;
}

</style>

Build the Menu System
It's time to build the menu system. This example creates four menus with associated triggers, but the procedure works identically with any number of menus <div id="menuBar" class="menuBar"></div>
<div id="About" class="menuTrigger">About Us</div>
<div id="Services" class="menuTrigger">Services</div>
<div id="Samples" class="menuTrigger">Samples</div>
<div id="Contact" class="menuTrigger">Contact Us</a></div>
<div id="mnuAbout" class="menu">
<p>About 1</p>
<p>About 2</p>
<p>About 3</p>
<p>About 4</p>
</div>
<div id="mnuServices" class="menu">
<p>Services 1</p>
<p>Services 2</p>
<p>Services 3</p>
</div>
<div id="mnuSamples" class="menu">
<p>Samples 1</p>
<p>Samples 2</p>
<p>Samples 3</p>
<p>Samples 4</p>
<p>Samples 5</p>
</div>
<div id="mnuContact" class="menu">
<p>Contact 1</p>
<p>Contact 2</p>
<p>Contact 3</p>
<p>Contact 4</p>
</div>


Write the Code
Menu systems really only do three things:
1. Show the appropriate menu when the mouse enters a trigger
2. Hide any other menu
3. Keep track of which menu is currently visible

One way to translate the preceding pseudo-code into JavaScript is: var mnuSelected = '';
function showMenu(menu){
hideMenu(mnuSelected);
document.getElementById(menu).style.visibility = 'visible';
mnuSelected = menu;
}
function hideMenu(menu){
if(mnuSelected!='')
document.getElementById(menu).style.visibility = 'hidden';
}


The mnuSelected variable keeps track of the current menu while the two functions show or hide the respective menu. That was pretty simple! The only thing left to do in code is the positioning.

function init(){
if(document.all){
aWidth = document.body.clientWidth;
document.getElementById('menuBar').style.width = aWidth;
}else{
aWidth = innerWidth;
document.getElementById('menuBar').style.width = aWidth-8;
}
document.getElementById('About').style.left = parseInt((aWidth/2 - 200));
document.getElementById('Services').style.left = parseInt((aWidth/2 - 100));
document.getElementById('Samples').style.left = parseInt(aWidth/2);
document.getElementById('Contact').style.left = parseInt((aWidth/2 + 100));
document.getElementById('mnuAbout').style.left =
document.getElementById('About').style.left;
document.getElementById('mnuServices').style.left =
document.getElementById('Services').style.left;
document.getElementById('mnuSamples').style.left =
document.getElementById('Samples').style.left;
document.getElementById('mnuContact').style.left =
document.getElementById('Contact').style.left;
}


Attach the Events
The last thing to do is to attach the events. Here is the modified About menu trigger:

<div id="About" class="menuTrigger" onMouseOut="this.style.color='';"
onMouseOver="showMenu('mnuAbout');
this.style.color='yellow';">About Us</div>

And here is the associated About menu:

<div id="mnuAbout" class="menu" onMouseOut="hideMenu(mnuSelected)"
onMouseOver="showMenu(mnuSelected)">

I included both mouse over and mouse out events for each menu as NS6 fires a mouse out event during the transition from the trigger to the menu.

The final touch is to modify the menu items so that they highlight when the mouse passes over them. One possible solution is to modify each item in the menu so that it looks like this:

<p onMouseOver="this.style.backgroundColor='red'"
onMouseOut="this.style.backgroundColor=''">
<a href="#">About 1</a></p>

Once again I wrapped the text in an <a> element but I assume that each menu item will have some function to perform. You can replace the ⌠# with an appropriate call.

To make the system work, modify the <body> element so that it calls init(). I've also included an onResize event so that the window will reposition the menus and resize the menu bar whenever the user resizes the window:

<body onLoad="init()" onResize="history.go(0)">

Add Sub-Menus
Adding sub-menus to the system is almost as intuitive as implementing the main menus. To illustrate, I'll add a sub-menu to the first mnuAbout menu item. Start by declaring the menu inside a <div> element:

<div id="mnuAboutSub1" class="menu" style="top: 30">
<p onMouseOver="this.style.backgroundColor='red'"
onMouseOut="this.style.backgroundColor=''">
<a href="#">Sub About 1</a></p>
<p onMouseOver="this.style.backgroundColor='red'"
onMouseOut="this.style.backgroundColor=''">
<a href="#">Sub About 1</a></p>
<p onMouseOver="this.style.backgroundColor='red'"
onMouseOut="this.style.backgroundColor=''">
<a href="#">Sub About 1</a></p>
<p onMouseOver="this.style.backgroundColor='red'"
onMouseOut="this.style.backgroundColor=''">
<a href="#">Sub About 1</a></p>
</div>


Set the top of the sub-menu to 30 pixels. Since the item that triggers the sub-menu is a <p> element, not a <div>, and it has no positioning style rules, I arrived at the number through trial and error. The number 30 seemed to work best for both IE5 and NS6. From a readability standpoint, this seemed a simpler approach than setting each menu item in a <div> and positioning it dynamically. It's imperfect but it works.

Now, add two functions and a variable to keep track of the currently visible sub-menu:

var subMnuSelected = '';
function showSubMenu(menu){
hideSubMenu(subMnuSelected);
document.getElementById(menu).style.visibility = 'visible';
subMnuSelected = menu;
}
function hideSubMenu(menu){
if(subMnuSelected!='')
document.getElementById(menu).style.visibility = 'hidden';
}


These functions are nearly identical to those for the main menu system but they have a separate index because the menu that triggers the sub-menu should stay visible while the sub-menu is visible. Using the functions for the main system would hide the trigger menu while showing the sub-menu.

To set the sub-menu's left property, add this code to the end of the init() function:

document.getElementById('mnuAboutSub1').style.left =
parseInt(document.getElementById('About').style.le ft) + 100;

Now its'time to attach the events. You'll have to modify the main menu triggers like this:

<div id="About" class="menuTrigger" onMouseOut="this.style.color='';"
onMouseOver="showMenu('mnuAbout');
hideSubMenu(subMnuSelected);this.style.color='yell ow';">
About Us
</div>

Next, modify the mnuAbout <div> so that it hides any sub-menu in the onMouseOut event:

<div id="mnuAbout" class="menu"
onMouseOut="hideMenu(mnuSelected);hideSubMenu(subMnuSelected); "
onMouseOver="showMenu(mnuSelected)">

Finally, modify the About 1 <p> element to show the sub-menu:

<p onMouseOver="this.style.backgroundColor='red';
showSubMenu('mnuAboutSub1');"
onMouseOut="this.style.backgroundColor='';
event.cancelBubble=true;">
<a href="#">About 1</a></p>

The only code of interest here is the call to event.cancelBubble. Without canceling the event in the <p> element, IE5 will propagate the event to the parent <div> where hideSubMenu() is called. The result would be that the sub-menu would become visible and then immediately disappear. That's not very user friendly!

With a little work, this simple menu system can do many things. For example, you have the ability to place your menus wherever you'd like. I used a horizontal menu bar but implementing a vertical bar shouldn't be all that difficult. Just match the top property of the menus to the triggers instead of the left when positioning. This is what DHTML is supposed to be like: a unified object model, an intuitive design process, and no bloated graphics. It's getting to be fun again!
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump



All times are GMT -5. The time now is 02:46 AM.



Powered by: vBulletin Version 3.0.3
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
All content Copyright ©1999 - 2010, Programmers Resource, unless otherwise noted.