PDA

View Full Version : Sub-menus for chrome menu



peterjtracey
05-05-2008, 06:48 PM
1) Script Title: Chrome CSS Drop Down Menu (v2.01)

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex1/chrome/index.htm

3) Describe problem:
I've modified chrome.js to allow for sub-menus, menus that appear to the right of highlighted drop-down menu items. I noticed a bunch of requests for this feature on the forums, so I'm posting the code here. They work just like regular menus, where you add rel="[id]" to the A element and include a div with the [id] referenced.

Add the following to the end of chrome.js, before the last }


,
subswipeeffect:function(){
if (this.subbottomclip<parseInt(this.subdropmenuobj.offsetHeight)){
this.subbottomclip+=10+(this.subbottomclip/10) //unclip drop down menu visibility gradually
this.subdropmenuobj.style.clip="rect(0 auto "+this.subbottomclip+"px 0)"
}
else
return
this.subswipetimer=setTimeout("cssdropdown.subswipeeffect()", 10)
},

subshowhide:function(obj, e){
if (this.ie || this.firefox)
this.subdropmenuobj.style.left=this.subdropmenuobj.style.top="-500px"
if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover"){
if (this.enableswipe==1){
if (typeof this.subswipetimer!="undefined")
clearTimeout(this.subswipetimer)
obj.clip="rect(0 auto 0 0)" //hide menu via clipping
this.subbottomclip=0
this.subswipeeffect()
}
obj.visibility="visible"
}
else if (e.type=="click")
obj.visibility="hidden"
},

subclearbrowseredge:function(obj, whichedge){
var edgeoffset=0
if (whichedge=="rightedge"){
var windowedge=this.ie && !window.opera? this.iecompattest().scrollLeft+this.iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
this.subdropmenuobj.contentmeasure=this.subdropmenuobj.offsetWidth
if (windowedge-this.subdropmenuobj.x < this.subdropmenuobj.contentmeasure) //move menu to the left?
edgeoffset=this.subdropmenuobj.contentmeasure-obj.offsetWidth
}
else{
var topedge=this.ie && !window.opera? this.iecompattest().scrollTop : window.pageYOffset
var windowedge=this.ie && !window.opera? this.iecompattest().scrollTop+this.iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
this.subdropmenuobj.contentmeasure=this.subdropmenuobj.offsetHeight
if (windowedge-this.subdropmenuobj.y < this.subdropmenuobj.contentmeasure){ //move up?
edgeoffset=this.subdropmenuobj.contentmeasure+obj.offsetHeight
if ((this.subdropmenuobj.y-topedge)<this.subdropmenuobj.contentmeasure) //up no good either?
edgeoffset=this.subdropmenuobj.y+obj.offsetHeight-topedge
}
}
return edgeoffset
},

subdynamichide:function(e){
var evtobj=window.event? window.event : e
if (this.ie&&!this.subdropmenuobj.contains(evtobj.toElement))
this.subdelayhidemenu()
else if (this.firefox&&e.currentTarget!= evtobj.relatedTarget&& !this.contains_firefox(evtobj.currentTarget, evtobj.relatedTarget))
this.subdelayhidemenu()
},

subdelayhidemenu:function(){
this.subdelayhide=setTimeout("cssdropdown.subdropmenuobj.style.visibility='hidden'; cssdropdown.hideshim(); cssdropdown.subparentobj.className = '';",this.disappeardelay) //hide menu
},

subclearhidemenu:function(){
if (this.subdelayhide!="undefined")
clearTimeout(this.subdelayhide)
},


subdropit:function(obj, e, dropmenuID){
if (this.subdropmenuobj!=null) //hide previous menu
this.subdropmenuobj.style.visibility="hidden" //hide menu
this.subclearhidemenu()
if (this.ie||this.firefox){
obj.onmouseout=function(){cssdropdown.subdelayhidemenu()}
obj.onclick=function(){return !cssdropdown.disablemenuclick} //disable main menu item link onclick?
this.subparentobj = obj;
this.subdropmenuobj=document.getElementById(dropmenuID)
this.subdropmenuobj.onmouseover=function(){cssdropdown.subclearhidemenu(); cssdropdown.clearhidemenu();cssdropdown.subparentobj.className = "subshown";
}
this.subdropmenuobj.onmouseout=function(e){cssdropdown.subdynamichide(e); cssdropdown.delayhidemenu();
}
this.subdropmenuobj.onclick=function(){cssdropdown.subdelayhidemenu()}
this.subshowhide(this.subdropmenuobj.style, e)
this.subdropmenuobj.x=this.getposOffset(obj, "left")+obj.offsetWidth
this.subdropmenuobj.y=this.getposOffset(obj, "top")
this.subdropmenuobj.style.left=this.subdropmenuobj.x+this.subclearbrowseredge(obj, "rightedge")+"px"
this.subdropmenuobj.style.top=this.subdropmenuobj.y-this.subclearbrowseredge(obj, "bottomedge")+1+"px"
this.positionshim() //call iframe shim function
}
}



Then replace the startchrome function with:

startchrome:function(){
for (var ids=0; ids<arguments.length; ids++){
var menuitems=document.getElementById(arguments[ids]).getElementsByTagName("a")
for (var i=0; i<menuitems.length; i++){
if (menuitems[i].getAttribute("rel")){
var relvalue=menuitems[i].getAttribute("rel")
menuitems[i].onmouseover=function(e){
var event=typeof e!="undefined"? e : window.event
cssdropdown.dropit(this,event,this.getAttribute("rel"))
}
var submenuitems=document.getElementById(menuitems[i].getAttribute("rel")).getElementsByTagName("a");
for (var j=0; j<submenuitems.length; j++){
if (submenuitems[j].getAttribute("rel")){
submenuitems[j].onmouseover=function(e){
var event=typeof e!="undefined"? e : window.event
cssdropdown.subdropit(this,event,this.getAttribute("rel"))
}
}
}

}
}
}
if (window.createPopup && !window.XmlHttpRequest){ //if IE5.5 to IE6, create iframe for iframe shim technique
document.write('<IFRAME id="iframeshim" src="" style="display: none; left: 0; top: 0; z-index: 90; position: absolute; filter: progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)" frameBorder="0" scrolling="no"></IFRAME>')
this.shimobject=document.getElementById("iframeshim") //reference iframe object
}
},

peterjtracey
05-05-2008, 06:50 PM
Only issue is that as soon as I added the line:
document.getElementById(menuitems[i].getAttribute("rel")).getElementsByTagName("a")
within the
if (menuitems[i].getAttribute("rel")) {
the menus started appearing under a flash object I added for testing. Weird because that line shouldn't really be doing anything besides fetching elements. No problem with <select>s. This is in IE7.