12 · 10

A Simple JavaScript Drop Down Menu

This is an extremely versatile drop down menu script for ordinary links on your page, including image links. It can be activated either onMouseover or onClick. The menu intelligently determines whether the dropped menu is too close to the browser's edge, adjusting its positioning so it's always in view.

This script works in all the major DHTML browsers- IE4+, NS6+, and Opera7+. You can specify a valid default URL for each link for other browsers to navigate to. Cool!

This may look long but bear with me. It will pay off in the end!

Step 1

Insert the following style sheet and script into the <head> section of your page:

<style type="text/css"> #dropmenudiv{ position:absolute; border:1px solid black; border-bottom-width: 0; font:normal 12px Verdana; line-height:18px; z-index:100; } #dropmenudiv a{ width: 100%; display: block; text-indent: 3px; border-bottom: 1px solid black; padding: 1px 0; text-decoration: none; font-weight: bold; } #dropmenudiv a:hover{ /*hover background color*/ background-color: yellow; } </style> <script type="text/javascript"> //Contents for menu 1 var menu1=new Array() menu1[0]='JavaScript Kit' menu1[1]='Freewarejava.com' menu1[2]='Coding Forums' menu1[3]='CSS Drive' //Contents for menu 2, and so on var menu2=new Array() menu2[0]='CNN' menu2[1]='MSNBC' menu2[2]='BBC News' var menuwidth='165px' //default menu width var menubgcolor='lightyellow'  //menu bgcolor var disappeardelay=250  //menu disappear speed onMouseout (in miliseconds) var hidemenu_onclick="yes" //hide menu when user clicks within menu? /////No further editting needed var ie4=document.all var ns6=document.getElementById&&!document.all if (ie4||ns6) document.write('<div id="dropmenudiv" style="visibility:hidden;width:'+menuwidth+';background-color:'+menubgcolor+'" onMouseover="clearhidemenu()" onMouseout="dynamichide(event)"></div>') function getposOffset(what, offsettype){ var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop; var parentEl=what.offsetParent; while (parentEl!=null){ totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop; parentEl=parentEl.offsetParent; } return totaloffset; } function showhide(obj, e, visible, hidden, menuwidth){ if (ie4||ns6) dropmenuobj.style.left=dropmenuobj.style.top="-500px" if (menuwidth!=""){ dropmenuobj.widthobj=dropmenuobj.style dropmenuobj.widthobj.width=menuwidth } if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover") obj.visibility=visible else if (e.type=="click") obj.visibility=hidden } function iecompattest(){ return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body } function clearbrowseredge(obj, whichedge){ var edgeoffset=0 if (whichedge=="rightedge"){ var windowedge=ie4 && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15 dropmenuobj.contentmeasure=dropmenuobj.offsetWidth if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure) edgeoffset=dropmenuobj.contentmeasure-obj.offsetWidth } else{ var topedge=ie4 && !window.opera? iecompattest().scrollTop : window.pageYOffset var windowedge=ie4 && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18 dropmenuobj.contentmeasure=dropmenuobj.offsetHeight if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure){ //move up? edgeoffset=dropmenuobj.contentmeasure+obj.offsetHeight if ((dropmenuobj.y-topedge)<dropmenuobj.contentmeasure) //up no good either? edgeoffset=dropmenuobj.y+obj.offsetHeight-topedge } } return edgeoffset } function populatemenu(what){ if (ie4||ns6) dropmenuobj.innerHTML=what.join("") } function dropdownmenu(obj, e, menucontents, menuwidth){ if (window.event) event.cancelBubble=true else if (e.stopPropagation) e.stopPropagation() clearhidemenu() dropmenuobj=document.getElementById? document.getElementById("dropmenudiv") : dropmenudiv populatemenu(menucontents) if (ie4||ns6){ showhide(dropmenuobj.style, e, "visible", "hidden", menuwidth) dropmenuobj.x=getposOffset(obj, "left") dropmenuobj.y=getposOffset(obj, "top") dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")+"px" dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px" } return clickreturnvalue() } function clickreturnvalue(){ if (ie4||ns6) return false else return true } function contains_ns6(a, b) { while (b.parentNode) if ((b = b.parentNode) == a) return true; return false; } function dynamichide(e){ if (ie4&&!dropmenuobj.contains(e.toElement)) delayhidemenu() else if (ns6&&e.currentTarget!= e.relatedTarget&& !contains_ns6(e.currentTarget, e.relatedTarget)) delayhidemenu() } function hidemenu(e){ if (typeof dropmenuobj!="undefined"){ if (ie4||ns6) dropmenuobj.style.visibility="hidden" } } function delayhidemenu(){ if (ie4||ns6) delayhide=setTimeout("hidemenu()",disappeardelay) } function clearhidemenu(){ if (typeof delayhide!="undefined") clearTimeout(delayhide) } if (hidemenu_onclick=="yes") document.onclick=hidemenu </script>

Step 2

Having done the above, all that's left is setting up your link(s) so a menu drops down. The below sample HTML demonstrates two links, one with the menu dropping down onMouseover, and the other, onClick:

Somewhere | Somewhere2 (onclick)
The dropdownmenu() function accepts 4 parameters as shown:
dropdownmenu(this, event, menuarray, 'width')
Only customize the last two parameters (menuarray and 'width'), where: 3) Menuarray- The array contents you wish the menu to display (see code of Step 1). 4) Width- The width of the menu (pass in "" if you simply wish to use the default menu width). And that's about it!

More information on customizing the menu

Inside the code of Step 1, a few items are available for customization. Firstly, the style sheet can be used to add additional visual styling to the menu, excluding default menu width and background color, which are controlled by two variables within the script that follow. You can also specify the disappearance delay of the menu when the mouse moves out of it.
About the Author Kyle Reddoch is a Web Development Expert and Internet Guru located in Amarillo, TX. To learn more about him you can visit his website at KyleReddoch.com.