Results 1 to 3 of 3

Thread: Delay menu appearence in anylink CSS menu

  1. #1
    Join Date
    Feb 2009
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question Delay menu appearence in anylink CSS menu

    1) Script Title: AnyLink CSS Menu v2.0

    2) Script URL (on DD): http://www.dynamicdrive.com/dynamici...anylinkcss.htm

    3) Describe problem:

    Hello everyone.

    I'm looking to delay the menu from opening until the mouse cursor has hovered over the menu link for 1 second, currently the menu opens up instantly when the mouse cursor is over it, even if the mouse cursor is only traveling across it on its way to another menu link below it, in which case the menu covers the desired link, I know about the [click] suffix that can be added to make the menu open onClick but I need the menu to appear on mouse hover.

    Thank you very much

    Javascript code included below:

    Code:
    var anylinkcssmenu={
    
    menusmap: {},
    effects: {delayhide: 200, shadow:{enabled:true, opacity:0.3, depth: [5, 5]}, fade:{enabled:true, duration:400}}, //customize menu effects
    
    dimensions: {},
    
    getoffset:function(what, offsettype){
    	return (what.offsetParent)? what[offsettype]+this.getoffset(what.offsetParent, offsettype) : what[offsettype]
    },
    
    getoffsetof:function(el){
    	el._offsets={left:this.getoffset(el, "offsetLeft"), top:this.getoffset(el, "offsetTop"), h: el.offsetHeight}
    },
    
    getdimensions:function(menu){
    	this.dimensions={anchorw:menu.anchorobj.offsetWidth, anchorh:menu.anchorobj.offsetHeight,
    		docwidth:(window.innerWidth ||this.standardbody.clientWidth)-20,
    		docheight:(window.innerHeight ||this.standardbody.clientHeight)-15,
    		docscrollx:window.pageXOffset || this.standardbody.scrollLeft,
    		docscrolly:window.pageYOffset || this.standardbody.scrollTop
    	}
    	if (!this.dimensions.dropmenuw){
    		this.dimensions.dropmenuw=menu.dropmenu.offsetWidth
    		this.dimensions.dropmenuh=menu.dropmenu.offsetHeight
    	}
    },
    
    isContained:function(m, e){
    	var e=window.event || e
    	var c=e.relatedTarget || ((e.type=="mouseover")? e.fromElement : e.toElement)
    	while (c && c!=m)try {c=c.parentNode} catch(e){c=m}
    	if (c==m)
    		return true
    	else
    		return false
    },
    
    setopacity:function(el, value){
    	el.style.opacity=value
    	if (typeof el.style.opacity!="string"){ //if it's not a string (ie: number instead), it means property not supported
    		el.style.MozOpacity=value
    		if (el.filters){
    			el.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity="+ value*100 +")"
    		}
    	}
    },
    
    showmenu:function(menuid){
    	var menu=anylinkcssmenu.menusmap[menuid]
    	clearTimeout(menu.hidetimer)
    	this.getoffsetof(menu.anchorobj)
    	this.getdimensions(menu)
    	var posx=menu.anchorobj._offsets.left + (menu.orientation=="lr"? this.dimensions.anchorw : 0) //base x pos
    	var posy=menu.anchorobj._offsets.top+this.dimensions.anchorh - (menu.orientation=="lr"? this.dimensions.anchorh : 0)//base y pos
    	if (posx+this.dimensions.dropmenuw+this.effects.shadow.depth[0]>this.dimensions.docscrollx+this.dimensions.docwidth){ //drop left instead?
    		posx=posx-this.dimensions.dropmenuw + (menu.orientation=="lr"? -this.dimensions.anchorw : this.dimensions.anchorw)
    	}
    	if (posy+this.dimensions.dropmenuh>this.dimensions.docscrolly+this.dimensions.docheight){  //drop up instead?
    		posy=Math.max(posy-this.dimensions.dropmenuh - (menu.orientation=="lr"? -this.dimensions.anchorh : this.dimensions.anchorh), this.dimensions.docscrolly) //position above anchor or window's top edge
    	}
    	if (this.effects.fade.enabled){
    		this.setopacity(menu.dropmenu, 0) //set opacity to 0 so menu appears hidden initially
    		if (this.effects.shadow.enabled)
    			this.setopacity(menu.shadow, 0) //set opacity to 0 so shadow appears hidden initially
    	}
    	menu.dropmenu.setcss({left:posx+'px', top:posy+'px', visibility:'visible'})
    	if (this.effects.shadow.enabled)
    		menu.shadow.setcss({left:posx+anylinkcssmenu.effects.shadow.depth[0]+'px', top:posy+anylinkcssmenu.effects.shadow.depth[1]+'px', visibility:'visible'})
    	if (this.effects.fade.enabled){
    		clearInterval(menu.animatetimer)
    		menu.curanimatedegree=0
    		menu.starttime=new Date().getTime() //get time just before animation is run
    		menu.animatetimer=setInterval(function(){anylinkcssmenu.revealmenu(menuid)}, 20)
    	}
    },
    
    revealmenu:function(menuid){
    	var menu=anylinkcssmenu.menusmap[menuid]
    	var elapsed=new Date().getTime()-menu.starttime //get time animation has run
    	if (elapsed<this.effects.fade.duration){
    		this.setopacity(menu.dropmenu, menu.curanimatedegree)
    		if (this.effects.shadow.enabled)
    			this.setopacity(menu.shadow, menu.curanimatedegree*this.effects.shadow.opacity)
    	}
    	else{
    		clearInterval(menu.animatetimer)
    		this.setopacity(menu.dropmenu, 1)
    		menu.dropmenu.style.filter=""
    	}
    	menu.curanimatedegree=(1-Math.cos((elapsed/this.effects.fade.duration)*Math.PI)) / 2
    },
    
    setcss:function(param){
    	for (prop in param){
    		this.style[prop]=param[prop]
    	}
    },
    
    hidemenu:function(menuid){
    	var menu=anylinkcssmenu.menusmap[menuid]
    	clearInterval(menu.animatetimer)
    	menu.dropmenu.setcss({visibility:'hidden', left:0, top:0})
    	menu.shadow.setcss({visibility:'hidden', left:0, top:0})
    },
    
    getElementsByClass:function(targetclass){
    	if (document.querySelectorAll)
    		return document.querySelectorAll("."+targetclass)
    	else{
    		var classnameRE=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "i") //regular expression to screen for classname
    		var pieces=[]
    		var alltags=document.all? document.all : document.getElementsByTagName("*")
    		for (var i=0; i<alltags.length; i++){
    			if (typeof alltags[i].className=="string" && alltags[i].className.search(classnameRE)!=-1)
    				pieces[pieces.length]=alltags[i]
    		}
    		return pieces
    	}
    },
    
    addEvent:function(targetarr, functionref, tasktype){
    	if (targetarr.length>0){
    		var target=targetarr.shift()
    		if (target.addEventListener)
    			target.addEventListener(tasktype, functionref, false)
    		else if (target.attachEvent)
    			target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)})
    		this.addEvent(targetarr, functionref, tasktype)
    	}
    },
    
    setupmenu:function(targetclass, anchorobj, pos){
    	this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body
    	var relattr=anchorobj.getAttribute("rel")
    	var dropmenuid=relattr.replace(/\[(\w+)\]/, '')
    	var menu=this.menusmap[targetclass+pos]={
    		id: targetclass+pos,
    		anchorobj: anchorobj,	
    		dropmenu: document.getElementById(dropmenuid),
    		revealtype: (relattr.length!=dropmenuid.length && RegExp.$1=="click")? "click" : "mouseover",
    		orientation: anchorobj.getAttribute("rev")=="lr"? "lr" : "ud",
    		shadow: document.createElement("div")
    	}
    	menu.anchorobj._internalID=targetclass+pos
    	menu.anchorobj._isanchor=true
    	menu.dropmenu._internalID=targetclass+pos
    	menu.shadow._internalID=targetclass+pos
    	menu.shadow.className="anylinkshadow"
    	document.body.appendChild(menu.dropmenu) //move drop down div to end of page
    	document.body.appendChild(menu.shadow)
    	menu.dropmenu.setcss=this.setcss
    	menu.shadow.setcss=this.setcss
    	menu.shadow.setcss({width: menu.dropmenu.offsetWidth+"px", height:menu.dropmenu.offsetHeight+"px"})
    	this.setopacity(menu.shadow, this.effects.shadow.opacity)
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOVER event for anchor, dropmenu, shadow
    		var menu=anylinkcssmenu.menusmap[this._internalID]
    		if (this._isanchor && menu.revealtype=="mouseover" && !anylinkcssmenu.isContained(this, e)){ //event for anchor
    			anylinkcssmenu.showmenu(menu.id)
    		}
    		else if (typeof this._isanchor=="undefined"){ //event for drop down menu and shadow
    			clearTimeout(menu.hidetimer)
    		}
    	}, "mouseover")
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOUT event for anchor, dropmenu, shadow
    		if (!anylinkcssmenu.isContained(this, e)){
    			var menu=anylinkcssmenu.menusmap[this._internalID]
    			menu.hidetimer=setTimeout(function(){anylinkcssmenu.hidemenu(menu.id)}, anylinkcssmenu.effects.delayhide)
    		}
    	}, "mouseout")
    	this.addEvent([menu.anchorobj, menu.dropmenu], function(e){ //CLICK event for anchor, dropmenu
    		var menu=anylinkcssmenu.menusmap[this._internalID]
    		if ( this._isanchor && menu.revealtype=="click"){
    			if (menu.dropmenu.style.visibility=="visible")
    				anylinkcssmenu.hidemenu(menu.id)
    			else
    				anylinkcssmenu.showmenu(menu.id)
    			if (e.preventDefault)
    				e.preventDefault()
    			return false
    		}
    		else
    			menu.hidetimer=setTimeout(function(){anylinkcssmenu.hidemenu(menu.id)}, anylinkcssmenu.effects.delayhide)
    	}, "click")
    },
    
    init:function(targetclass){
    	var anchors=this.getElementsByClass(targetclass)
    	for (var i=0; i<anchors.length; i++){
    		this.setupmenu(targetclass, anchors[i], i)
    	}
    }
    
    }

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I think one second is too long, about a third of a second would probably be better but you can play with that.

    Change (in anylinkcssmenu.js):

    Code:
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOVER event for anchor, dropmenu, shadow
    		var menu=anylinkcssmenu.menusmap[this._internalID]
    		if (this._isanchor && menu.revealtype=="mouseover" && !anylinkcssmenu.isContained(this, e)){ //event for anchor
    			anylinkcssmenu.showmenu(menu.id)
    		}
    		else if (typeof this._isanchor=="undefined"){ //event for drop down menu and shadow
    			clearTimeout(menu.hidetimer)
    		}
    	}, "mouseover")
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOUT event for anchor, dropmenu, shadow
    		if (!anylinkcssmenu.isContained(this, e)){
    			var menu=anylinkcssmenu.menusmap[this._internalID]
    			menu.hidetimer=setTimeout(function(){anylinkcssmenu.hidemenu(menu.id)}, anylinkcssmenu.effects.delayhide)
    		}
    	}, "mouseout")
    to:

    Code:
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOVER event for anchor, dropmenu, shadow
    		var menu=anylinkcssmenu.menusmap[this._internalID]
    		if (this._isanchor && menu.revealtype=="mouseover" && !anylinkcssmenu.isContained(this, e)){ //event for anchor
    			anylinkcssmenu.timer=setTimeout(function(){anylinkcssmenu.showmenu(menu.id);}, 300);
    		}
    		else if (typeof this._isanchor=="undefined"){ //event for drop down menu and shadow
    			clearTimeout(menu.hidetimer)
    		}
    	}, "mouseover")
    	this.addEvent([menu.anchorobj, menu.dropmenu, menu.shadow], function(e){ //MOUSEOUT event for anchor, dropmenu, shadow
    		if (!anylinkcssmenu.isContained(this, e)){
    			clearTimeout(anylinkcssmenu.timer);
    			var menu=anylinkcssmenu.menusmap[this._internalID]
    			menu.hidetimer=setTimeout(function(){anylinkcssmenu.hidemenu(menu.id)}, anylinkcssmenu.effects.delayhide)
    		}
    	}, "mouseout")
    The red 300 in the above is for about a third of a second delay, 1000 would be a full second delay.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. The Following User Says Thank You to jscheuer1 For This Useful Post:

    roylazarovich (02-07-2009)

  4. #3
    Join Date
    Feb 2009
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default

    Thank you very much, jscheuer1.

    It worked!, hopefully other users will find this useful too

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •