[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Mouse-over tabs website navigation / Javascript

Posted on 2009-05-08
6
Medium Priority
?
1,586 Views
Last Modified: 2013-11-19
I am using a navigation menu script on a website that enables mouse-over of tabs to display a sub-menu beneath. Currently, when removing the mouse from the tab, the sub-menu disappears again, which is correct. However, what I need is for the initial sub-menu to re-instate. It's difficult to describe, but is obvious when viewing the page:
http://www.cybersentinel.co.uk/test/

Hover over any one of the navigation tabs and you'll see the sub-menu display beneath (correctly). Remove the mouse from the tabs and the sub-nav is then blank - what needs to happen is for it to re-set to the 'homepage' sub-nav (with the 'home' tab highlighted white) as it was on the initial page load.

The JS script is here:
http://www.cybersentinel.co.uk/test/Scripts/mouseovertabs.js

The CSS is here:
http://www.cybersentinel.co.uk/test/Scripts/mouseovertabs.css

Any advice would be much appreciated.
0
Comment
Question by:beverleydunster
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 8

Expert Comment

by:Bobaran98
ID: 24342564
Take a look at the javascript below... I made some edits, and this should replace the entirety of your mouseovertabs.js file.

I'd like to think it'll work, but you'll just have to throw it out there and see-- obviously I can't really test it myself.  Regardless, I very carefully commented all of my changes (look for the text "Bobaran98", so maybe you can tweak it if you receive any error messages.  However, you're welcome to post any error messages here and we can tackle them together.  If we get it working, I don't care if you remove my comments-- it's not originally my code, after all!

Hope it works!

//Mouseover Tabs Menu: By http://www.dynamicdrive.com
//** Aug 4th, 08': Script creation date
//CHANGES: 5/9/2009 Bobaran98 - to reset tabs to original state on mouseout event
 
var uberSelected;	//added by Bobaran98 5/9/2009
 
var mouseovertabsmenu={
 
disappeardelay: 250, //set delay in miliseconds before sub menu disappears onmouseout
ajaxloadingmsg: 'Loading Sub Menu Contents...', //Message to show inside sub menu while fetching contents
 
///////No need to edit beyond here//////////////////////
 
tabsmenutree:{},
 
initializetabs:function(tabsmenuid, submenuid, tabcontentsLength, disappearBool){
	var tabmenu=document.getElementById(tabsmenuid)
	var tablinks=tabmenu.getElementsByTagName("a")
	var submenu=document.getElementById(submenuid)
	var selected=null, tablinks_count=0
	for (var i=0; i<tablinks.length; i++){
		tablinks[i]._parentid=tabsmenuid
		var relattr=tablinks[i].getAttribute("rel")
		if (/^gotsubmenu/i.test(relattr) && tablinks_count<tabcontentsLength){ //if "rel" attribute starts with="gotsubmenu" and a tab content exists for this tab based on its order
			tablinks[i]._pos=tablinks_count //remember position of this tab relative to its active peers
			if (relattr.indexOf("[selected]")!=-1){
				selected=tablinks_count
			}
			this.addEvent(tablinks[i], function(){
				var tabsmenutree=mouseovertabsmenu.tabsmenutree[this._parentid]
				mouseovertabsmenu.clearhidetimer(tabsmenutree.submenu.hidetimer)
				mouseovertabsmenu.showsubmenu(this)
			}, "mouseover")
			tablinks_count++
			this.tabsmenutree[tabsmenuid].tabs.push(tablinks[i]) //add this tab to tab collection
		}
		else{ //else for regular tab links (with no "rel" attribute)
			this.addEvent(tablinks[i], function(){
				mouseovertabsmenu.hidesubmenu(this._parentid)
			}, "mouseover")
		}
	}
	this.addEvent(submenu, function(e){
		mouseovertabsmenu.clearhidetimer(this.hidetimer)
	}, "mouseover")
	if (disappearBool==true){
		this.addEvent(submenu, function(e){ //hide submenu contents when mouse rolls out of submenu DIV
			if (!mouseovertabsmenu.isContained(this, e)){
				var cursubmenuobj=this
				// commented out by Bobaran98 5/9/2009:
				//this.hidetimer=setTimeout(function(){mouseovertabsmenu.hidesubmenu(cursubmenuobj._parentid)}, mouseovertabsmenu.disappeardelay)
				// added by Bobaran98 5/9/2009:
				this.hidetimer=setTimeout(function(){resettabs(cursubmenuobj._parentid,uberSelected)}, mouseovertabsmenu.disappeardelay)
			}
		}, "mouseout")
	}
	var urlselected=this.urlparamselect(tabsmenuid)
	//return position of selected tab (relative to its peers), or null
	return typeof urlselected=="number"? urlselected : document.getElementById(urlselected)? document.getElementById(urlselected)._pos : selected
},
 
resettabs:function(hidemenuID, showmenuID){		//function added by Bobaran98 5/9/2009
	mouseovertabsmenu.hidesubmenu(hidemenuID)
	innerdivs[showmenuID].style.display="block"
	this.css(tabsmenutree.tabs[showmenuID], "selected", "add")
	tabsmenutree.submenu._prevselected=showmenuID
},
 
ajaxload:function(tabsmenuid, submenuid, disappearBool, url){
	var page_request = false
	if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
		try {
		page_request = new ActiveXObject("Msxml2.XMLHTTP")
		} 
		catch (e){
			try{
			page_request = new ActiveXObject("Microsoft.XMLHTTP")
			}
			catch (e){}
		}
	}
	else if (window.XMLHttpRequest) // if Mozilla, Safari etc
		page_request = new XMLHttpRequest()
	else
		return false
	var tabsmenutree=this.tabsmenutree[tabsmenuid]
	tabsmenutree.submenu.innerHTML=this.ajaxloadingmsg
	var ajaxfriendlyurl=url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/") 
	page_request.onreadystatechange=function(){
		mouseovertabsmenu.ajaxpopulate(page_request, tabsmenuid, submenuid, disappearBool, ajaxfriendlyurl)
	}
	var bustcache=(ajaxfriendlyurl.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
	page_request.open('GET', ajaxfriendlyurl+bustcache, true)
	page_request.send(null)
},
 
ajaxpopulate:function(page_request, tabsmenuid, submenuid, disappearBool, url){
	if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)){
		var tabsmenutree=this.tabsmenutree[tabsmenuid]
		tabsmenutree.submenu.innerHTML=page_request.responseText
		var innerdivs=tabsmenutree.submenu.getElementsByTagName("div")
		for (var i=0; i<innerdivs.length; i++){
			if (/tabsmenucontent/i.test(innerdivs[i].className)){
				tabsmenutree.submenu_divs.push(innerdivs[i])
			}
		}
		var selected=this.initializetabs(tabsmenuid, submenuid, tabsmenutree.submenu_divs.length, disappearBool)
		if (selected!=null && selected<tabsmenutree.submenu_divs.length){
			uberSelected = selected;	//added by Bobaran98 5/9/2009
			innerdivs[selected].style.display="block"
			this.css(tabsmenutree.tabs[selected], "selected", "add")
			tabsmenutree.submenu._prevselected=selected
		}
	}
},
 
showsubmenu:function(linkobj){
	var tabsmenutree=this.tabsmenutree[linkobj._parentid]
	this.hidesubmenu(linkobj._parentid)
	var selected=parseInt(linkobj._pos)
	tabsmenutree.submenu_divs[selected].style.display="block"
	this.css(tabsmenutree.tabs[selected], "selected", "add")
	tabsmenutree.submenu._prevselected=selected
},
 
hidesubmenu:function(tabsmenuid){
	var tabsmenutree=this.tabsmenutree[tabsmenuid]
	var prevselectedindex=tabsmenutree.submenu._prevselected
	if (typeof prevselectedindex!="undefined"){
		tabsmenutree.submenu_divs[prevselectedindex].style.display="none"
		this.css(tabsmenutree.tabs[prevselectedindex], "selected", "remove")
	}
},
 
clearhidetimer:function(timerid){
	if (timerid)
		clearTimeout(timerid)
},
 
css:function(el, targetclass, action){
	var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
	if (action=="check")
		return needle.test(el.className)
	else if (action=="remove")
		el.className=el.className.replace(needle, "")
	else if (action=="add" && !needle.test(el.className))
		el.className+=" "+targetclass
},
 
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
},
 
urlparamselect:function(tabsmenuid){
	var result=window.location.search.match(new RegExp(tabsmenuid+"=(\\w+)", "i")) //check for "?tabsmenuid=id_or_pos_of_selected_tab" in URL
	var selectedtabstr=RegExp.$1
	return /^\d+$/.test(selectedtabstr)? parseInt(selectedtabstr) : selectedtabstr //return position or ID of selected tab (or null if niether found)
},
 
 
addEvent:function(target, functionref, tasktype){
	if (target.addEventListener)
		target.addEventListener(tasktype, functionref, false);
	else if (target.attachEvent)
		target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});
},
 
init:function(tabsmenuid, submenuid, disappearBool){
	this.tabsmenutree[tabsmenuid]={} 
	this.tabsmenutree[tabsmenuid].tabs=[] //array referencing the active tab links in this menu (ones with a "rel=gotsubmenu" attr)
	this.tabsmenutree[tabsmenuid].submenu=null //reference submenu DIV for this menu
	this.tabsmenutree[tabsmenuid].submenu_divs=[] //array referencing the submenu contents (external DIVs with class="tabsmenucontent")
	var submenu=document.getElementById(submenuid)
	submenu._parentid=tabsmenuid
	this.tabsmenutree[tabsmenuid].submenu=submenu //remember this DIV as menu's submenu container
	var remoteurl=submenu.getElementsByTagName("a")[0].getAttribute("href")
	this.ajaxload(tabsmenuid, submenuid, disappearBool, remoteurl)
}
 
}
 
document.write('<style type="text/css">\n.tabsmenucontent{display:none}\n</style>')

Open in new window

0
 

Author Comment

by:beverleydunster
ID: 24343362
Hi

Thanks very much for this - it seems to have had an effect - but not quite the right one. The entire .js file has been updated with your code - see the result here:
http://www.cybersentinel.co.uk/test/

I'm getting two JS errors in the browser, as below...

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Sky Broadband; GTB6; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; InfoPath.2; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Timestamp: Sat, 9 May 2009 11:45:53 UTC


Message: Object expected
Line: 53
Char: 42
Code: 0
URI: http://www.cybersentinel.co.uk/test/Scripts/mouseovertabs.js


Message: Object expected
Line: 53
Char: 42
Code: 0
URI: http://www.cybersentinel.co.uk/test/Scripts/mouseovertabs.js


0
 

Author Comment

by:beverleydunster
ID: 24344249
... I should just add that it does seem to maintain the sub-navigation when you mouse-out - but it's maintaining the sub-nav of the last tab hovered over - rather than reverting to the sub-navigation of the active tab.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:Bobaran98
ID: 24344283
Yep, I've got it figured out.  My changes don't make for the cleanest code in history, mostly because I haven't taken the time to figure out what every line of code does, but this should meet your needs just fine.  I did take a few minutes to setup a test bed here with your files, so I was able to test it and it works just fine.  So down below should be the fully operational JS file!

And just so you understand, this will work such that the navigation always defaults to your initially selected option-- it's not hardcoded to HOMEPAGE.  It just looks for whichever link option has:

rel="gotsubmenu[selected]"

Let me know if you have any more problems!
//Mouseover Tabs Menu: By http://www.dynamicdrive.com
//** Aug 4th, 08': Script creation date
//CHANGES: 5/9/2009 Bobaran98 - to reset tabs to original state on mouseout event; simple worakarounds only!
 
var uberSelected;	//added by Bobaran98 5/9/2009
var uberInnerDiv;	//added by Bobaran98 5/9/2009
var uberTabsMenuTree;	//added by Bobaran98 5/9/2009
 
var mouseovertabsmenu={
 
disappeardelay: 250, //set delay in miliseconds before sub menu disappears onmouseout
ajaxloadingmsg: 'Loading Sub Menu Contents...', //Message to show inside sub menu while fetching contents
 
///////No need to edit beyond here//////////////////////
 
tabsmenutree:{},
 
initializetabs:function(tabsmenuid, submenuid, tabcontentsLength, disappearBool){
	var tabmenu=document.getElementById(tabsmenuid)
	var tablinks=tabmenu.getElementsByTagName("a")
	var submenu=document.getElementById(submenuid)
	var selected=null, tablinks_count=0
	for (var i=0; i<tablinks.length; i++){
		tablinks[i]._parentid=tabsmenuid
		var relattr=tablinks[i].getAttribute("rel")
		if (/^gotsubmenu/i.test(relattr) && tablinks_count<tabcontentsLength){ //if "rel" attribute starts with="gotsubmenu" and a tab content exists for this tab based on its order
			tablinks[i]._pos=tablinks_count //remember position of this tab relative to its active peers
			if (relattr.indexOf("[selected]")!=-1){
				selected=tablinks_count
			}
			this.addEvent(tablinks[i], function(){
				var tabsmenutree=mouseovertabsmenu.tabsmenutree[this._parentid]
				mouseovertabsmenu.clearhidetimer(tabsmenutree.submenu.hidetimer)
				mouseovertabsmenu.showsubmenu(this)
			}, "mouseover")
			tablinks_count++
			this.tabsmenutree[tabsmenuid].tabs.push(tablinks[i]) //add this tab to tab collection
		}
		else{ //else for regular tab links (with no "rel" attribute)
			this.addEvent(tablinks[i], function(){
				mouseovertabsmenu.hidesubmenu(this._parentid)
			}, "mouseover")
		}
	}
	this.addEvent(submenu, function(e){
		mouseovertabsmenu.clearhidetimer(this.hidetimer)
	}, "mouseover")
	if (disappearBool==true){
		this.addEvent(submenu, function(e){ //hide submenu contents when mouse rolls out of submenu DIV
			if (!mouseovertabsmenu.isContained(this, e)){
				var cursubmenuobj=this
				// commented out by Bobaran98 5/9/2009:
				//this.hidetimer=setTimeout(function(){mouseovertabsmenu.hidesubmenu(cursubmenuobj._parentid)}, mouseovertabsmenu.disappeardelay)
				// added by Bobaran98 5/9/2009:
				this.hidetimer=setTimeout(function(){mouseovertabsmenu.resettabs(cursubmenuobj._parentid,uberSelected)}, mouseovertabsmenu.disappeardelay)
			}
		}, "mouseout")
	}
	var urlselected=this.urlparamselect(tabsmenuid)
	//return position of selected tab (relative to its peers), or null
	return typeof urlselected=="number"? urlselected : document.getElementById(urlselected)? document.getElementById(urlselected)._pos : selected
},
 
resettabs:function(hidemenuID, showmenuID){		//function added by Bobaran98 5/9/2009
	mouseovertabsmenu.hidesubmenu(hidemenuID)
	uberInnerDiv[showmenuID].style.display="block"
	this.css(uberTabsMenuTree.tabs[showmenuID], "selected", "add")
	uberTabsMenuTree.submenu._prevselected=showmenuID
},
 
ajaxload:function(tabsmenuid, submenuid, disappearBool, url){
	var page_request = false
	if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
		try {
		page_request = new ActiveXObject("Msxml2.XMLHTTP")
		} 
		catch (e){
			try{
			page_request = new ActiveXObject("Microsoft.XMLHTTP")
			}
			catch (e){}
		}
	}
	else if (window.XMLHttpRequest) // if Mozilla, Safari etc
		page_request = new XMLHttpRequest()
	else
		return false
	var tabsmenutree=this.tabsmenutree[tabsmenuid]
	tabsmenutree.submenu.innerHTML=this.ajaxloadingmsg
	//var ajaxfriendlyurl=url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/") 
	var ajaxfriendlyurl=url.replace(/^http:\/\/[^\/]+\//i, "http://www.cybersentinel.co.uk/")		//put me back the way i was!
	page_request.onreadystatechange=function(){
		mouseovertabsmenu.ajaxpopulate(page_request, tabsmenuid, submenuid, disappearBool, ajaxfriendlyurl)
	}
	var bustcache=(ajaxfriendlyurl.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
	page_request.open('GET', ajaxfriendlyurl+bustcache, true)
	page_request.send(null)
},
 
ajaxpopulate:function(page_request, tabsmenuid, submenuid, disappearBool, url){
	if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1)){
		var tabsmenutree=this.tabsmenutree[tabsmenuid]
		tabsmenutree.submenu.innerHTML=page_request.responseText
		var innerdivs=tabsmenutree.submenu.getElementsByTagName("div")
		for (var i=0; i<innerdivs.length; i++){
			if (/tabsmenucontent/i.test(innerdivs[i].className)){
				tabsmenutree.submenu_divs.push(innerdivs[i])
			}
		}
		var selected=this.initializetabs(tabsmenuid, submenuid, tabsmenutree.submenu_divs.length, disappearBool)
		if (selected!=null && selected<tabsmenutree.submenu_divs.length){
			uberSelected = selected;	//added by Bobaran98 5/9/2009
			uberInnerDiv = innerdivs;	//added by Bobaran98 5/9/2009
			uberTabsMenuTree = tabsmenutree;	//added by Bobaran98 5/9/2009
			innerdivs[selected].style.display="block"
			this.css(tabsmenutree.tabs[selected], "selected", "add")
			tabsmenutree.submenu._prevselected=selected
		}
	}
},
 
showsubmenu:function(linkobj){
	var tabsmenutree=this.tabsmenutree[linkobj._parentid]
	this.hidesubmenu(linkobj._parentid)
	var selected=parseInt(linkobj._pos)
	tabsmenutree.submenu_divs[selected].style.display="block"
	this.css(tabsmenutree.tabs[selected], "selected", "add")
	tabsmenutree.submenu._prevselected=selected
},
 
hidesubmenu:function(tabsmenuid){
	var tabsmenutree=this.tabsmenutree[tabsmenuid]
	var prevselectedindex=tabsmenutree.submenu._prevselected
	if (typeof prevselectedindex!="undefined"){
		tabsmenutree.submenu_divs[prevselectedindex].style.display="none"
		this.css(tabsmenutree.tabs[prevselectedindex], "selected", "remove")
	}
},
 
clearhidetimer:function(timerid){
	if (timerid)
		clearTimeout(timerid)
},
 
css:function(el, targetclass, action){
	var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
	if (action=="check")
		return needle.test(el.className)
	else if (action=="remove")
		el.className=el.className.replace(needle, "")
	else if (action=="add" && !needle.test(el.className))
		el.className+=" "+targetclass
},
 
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
},
 
urlparamselect:function(tabsmenuid){
	var result=window.location.search.match(new RegExp(tabsmenuid+"=(\\w+)", "i")) //check for "?tabsmenuid=id_or_pos_of_selected_tab" in URL
	var selectedtabstr=RegExp.$1
	return /^\d+$/.test(selectedtabstr)? parseInt(selectedtabstr) : selectedtabstr //return position or ID of selected tab (or null if niether found)
},
 
 
addEvent:function(target, functionref, tasktype){
	if (target.addEventListener)
		target.addEventListener(tasktype, functionref, false);
	else if (target.attachEvent)
		target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});
},
 
init:function(tabsmenuid, submenuid, disappearBool){
	this.tabsmenutree[tabsmenuid]={} 
	this.tabsmenutree[tabsmenuid].tabs=[] //array referencing the active tab links in this menu (ones with a "rel=gotsubmenu" attr)
	this.tabsmenutree[tabsmenuid].submenu=null //reference submenu DIV for this menu
	this.tabsmenutree[tabsmenuid].submenu_divs=[] //array referencing the submenu contents (external DIVs with class="tabsmenucontent")
	var submenu=document.getElementById(submenuid)
	submenu._parentid=tabsmenuid
	this.tabsmenutree[tabsmenuid].submenu=submenu //remember this DIV as menu's submenu container
	var remoteurl=submenu.getElementsByTagName("a")[0].getAttribute("href")
	this.ajaxload(tabsmenuid, submenuid, disappearBool, remoteurl)
}
 
}
 
document.write('<style type="text/css">\n.tabsmenucontent{display:none}\n</style>')

Open in new window

0
 
LVL 8

Accepted Solution

by:
Bobaran98 earned 2000 total points
ID: 24344312
By the way, I noticed at least one word in your keywords listing for which we Americans have a variant spelling (paedophile/pedophile).  I'm not sure just how effective meta tags are these days in terms of influencing search results, but it can't hurt to include variants, at least if you've got any interest in generating sales across the pond.

Search engine optimization (or SEO) isn't at all my area of expertise, but if you're interested, I think we've got a fair amount of activity on EE discussing the topic.  Just searching for "search engine optimization" or "SEO" will get you a fair number of results, and if you've got specific questions, you could either search for them or ask.

I know, I know, unasked for advice. :-)  Good luck on your venture!
0
 

Author Closing Comment

by:beverleydunster
ID: 31579370
Bobaran98 - a real helpful expert. Never thought I'd get a solution to this but it works perfectly. Thank you so much for your help!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
Styling your websites can become very complex. Here I'll show how SASS can help you better organize, maintain and reuse your CSS code.
The viewer will learn how to count occurrences of each item in an array.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question