Jump to content

Great cross-browser working dynamic sidebar


kurt.santo
 Share

Recommended Posts

Hi guys, would like to share a script with you, which I have from a book by Christian Heilman (called Beginning JavaScript with DOM Scripting and Ajax). Not only can you expand the sub-sections, you can also make full use of all links as a tiny arrow symbol before nav listing lets you expand/collapse section. Works with all browsers (says in book and I tested as well with latest browsers including IE, FF and Netscape)...HTML could be sth like:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 	<title>Example: Dynamic Site Navigation</title>	<style type="text/css">		@import 'siteNavigation.css';	</style>	<script type="text/javascript" src="DOMhelp.js"></script>	<script type="text/javascript" src="siteNavigation.js"></script></head><body><ul id="nav"><li><strong>Products</strong>	<ul>    <li><A href="cms.htm">CMS solutions</A>    	<ul><li><A href="mini.htm">Mini CMS</A></li><li><A href="enterprise.htm">Enterprise CMS</A></li>    	</ul>   	</li>    </ul></li></ul></body></html>

Javascript is the following:

DOMhelp={	debugWindowId:'DOMhelpdebug',	init:function(){		if(!document.getElementById || !document.createTextNode){return;}	},	lastSibling:function(node){		var tempObj=node.parentNode.lastChild;		while(tempObj.nodeType!=1 && tempObj.previousSibling!=null){			tempObj=tempObj.previousSibling;		}		return (tempObj.nodeType==1)?tempObj:false;	},	firstSibling:function(node){		var tempObj=node.parentNode.firstChild;		while(tempObj.nodeType!=1 && tempObj.nextSibling!=null){			tempObj=tempObj.nextSibling;		}		return (tempObj.nodeType==1)?tempObj:false;	},	getText:function(node){		if(!node.hasChildNodes()){return false;}		var reg=/^\s+$/;		var tempObj=node.firstChild;		while(tempObj.nodeType!=3 && tempObj.nextSibling!=null || reg.test(tempObj.nodeValue)){			tempObj=tempObj.nextSibling;		}		return tempObj.nodeType==3?tempObj.nodeValue:false;	},	setText:function(node,txt){		if(!node.hasChildNodes()){return false;}		var reg=/^\s+$/;		var tempObj=node.firstChild;		while(tempObj.nodeType!=3 && tempObj.nextSibling!=null || reg.test(tempObj.nodeValue)){			tempObj=tempObj.nextSibling;		}		if(tempObj.nodeType==3){tempObj.nodeValue=txt}else{return false;}	},	createLink:function(to,txt){		var tempObj=document.createElement('a');		tempObj.appendChild(document.createTextNode(txt));		tempObj.setAttribute('href',to);		return tempObj;	},	createTextElm:function(elm,txt){		var tempObj=document.createElement(elm);		tempObj.appendChild(document.createTextNode(txt));		return tempObj;	},	closestSibling:function(node,direction){		var tempObj;		if(direction==-1 && node.previousSibling!=null){			tempObj=node.previousSibling;			while(tempObj.nodeType!=1 && tempObj.previousSibling!=null){				 tempObj=tempObj.previousSibling;			}		}else if(direction==1 && node.nextSibling!=null){			tempObj=node.nextSibling;			while(tempObj.nodeType!=1 && tempObj.nextSibling!=null){				 tempObj=tempObj.nextSibling;			}		}		return tempObj.nodeType==1?tempObj:false;	},	initDebug:function(){		if(DOMhelp.debug){DOMhelp.stopDebug();}		DOMhelp.debug=document.createElement('div');		DOMhelp.debug.setAttribute('id',DOMhelp.debugWindowId);		document.body.insertBefore(DOMhelp.debug,document.body.firstChild);	},	setDebug:function(bug){		if(!DOMhelp.debug){DOMhelp.initDebug();}		DOMhelp.debug.innerHTML+=bug+'\n';	},	stopDebug:function(){		if(DOMhelp.debug){			DOMhelp.debug.parentNode.removeChild(DOMhelp.debug);			DOMhelp.debug=null;		}	},	getKey:function(e){		if(window.event){	      var key = window.event.keyCode;	    } else if(e){	      var key=e.keyCode;	    }		return key;	},/* helper methods */	getTarget:function(e){		var target = window.event ? window.event.srcElement : e ? e.target : null;		if (!target){return false;}		while(target.nodeType!=1 && target.nodeName.toLowerCase()!='body'){			target=target.parentNode;		}		return target;	},	stopBubble:function(e){		if(window.event && window.event.cancelBubble){			window.event.cancelBubble = true;		} 		if (e && e.stopPropagation){			e.stopPropagation();		}	},	stopDefault:function(e){		if(window.event && window.event.returnValue){			window.event.returnValue = false;		} 		if (e && e.preventDefault){			e.preventDefault();		}	},	cancelClick:function(e){		if (window.event){			window.event.cancelBubble = true;			window.event.returnValue = false;		}		if (e && e.stopPropagation && e.preventDefault){			e.stopPropagation();			e.preventDefault();		}	},	addEvent: function(elm, evType, fn, useCapture){		if (elm.addEventListener){			elm.addEventListener(evType, fn, useCapture);			return true;		} else if (elm.attachEvent) {			var r = elm.attachEvent('on' + evType, fn);			return r;		} else {			elm['on' + evType] = fn;		}	},	cssjs:function(a,o,c1,c2){		switch (a){			case 'swap':				o.className=!DOMhelp.cssjs('check',o,c1)?o.className.replace(c2,c1).className.replace(c1,c2);			break;			case 'add':				if(!DOMhelp.cssjs('check',o,c1)){o.className+=o.className?' '+c1:c1;}			break;			case 'remove':				var rep=o.className.match(' '+c1)?' '+c1:c1;				o.className=o.className.replace(rep,'');			break;			case 'check':				var found=false;				var temparray=o.className.split(' ');				for(var i=0;i<temparray.length;i++){					if(temparray[i]==c1){found=true;}				}				return found;			break;		}	},    safariClickFix:function(){      return false;    }}DOMhelp.addEvent(window, 'load', DOMhelp.init, false);

and

sn={	dynamicClass:'dyn',	showClass:'show',	parentClass:'parent',	openClass:'open',	parentIndicator:'<img src="plus.gif" alt="open section" title="open section">',	openIndicator:'<img src="minus.gif" alt="close section" title="close section">',	navID:'nav',	init:function(){		var parentLI,triggerLink;		if(!document.getElementById || !document.createTextNode){return;}		var nav=document.getElementById(sn.navID);		if(!nav){return;}		DOMhelp.cssjs('add',nav,sn.dynamicClass);				var nested=nav.getElementsByTagName('ul');		for(var i=0;i<nested.length;i++){			parentLI=nested[i].parentNode;			triggerLink=document.createElement('a');			triggerLink.setAttribute('href','#')			triggerLink.innerHTML=sn.parentIndicator;			parentLI.insertBefore(triggerLink,parentLI.firstChild);			DOMhelp.addEvent(triggerLink,'click',sn.changeSection,false);			DOMhelp.cssjs('add',parentLI,sn.parentClass);					triggerLink.onclick=DOMhelp.safariClickFix;			if(parentLI.getElementsByTagName('strong').length>0){				DOMhelp.cssjs('add',parentLI,sn.openClass);						DOMhelp.cssjs('add',nested[i],sn.showClass);						parentLI.getElementsByTagName('a')[0].innerHTML=sn.openIndicator			}		}	},	changeSection:function(e){		var t=DOMhelp.getTarget(e);		while(t.nodeName.toLowerCase()!='a'){			t=t.parentNode;		}		var firstList=t.parentNode.getElementsByTagName('ul')[0];		if(DOMhelp.cssjs('check',firstList,sn.showClass)){			DOMhelp.cssjs('remove',firstList,sn.showClass)			DOMhelp.cssjs('swap',t.parentNode,sn.openClass,sn.parentClass);			t.innerHTML=sn.parentIndicator;		} else {			DOMhelp.cssjs('add',firstList,sn.showClass)			DOMhelp.cssjs('swap',t.parentNode,sn.openClass,sn.parentClass);			t.innerHTML=sn.openIndicator;		}		DOMhelp.cancelClick(e);	}}DOMhelp.addEvent(window,'load',sn.init,false);

Styling is as the following:

	*{		margin:0;		padding:0;		list-style:none;		border:none;	}	body{		font-family:arial,sans-serif;		background:#fff;		color:#333;		font-size:100.01%;	}	#nav{		font-size:.8em;		float:left;		width:14em;		padding:.5em;		background:#ddd;	}	#nav a{		text-decoration:none;		color:#000;	}	#nav ul{		margin-left:.5em;	}	#nav li{		padding:.2em 0;	}	#nav strong{		color:#696;	}		#nav.dyn li ul{		display:none;		}	#nav.dyn li ul.show{		display:block;		}	#nav.dyn li{		padding-left:32px;	}	#nav.dyn li.parent{		background:#fff;		padding-left:14px;	}	#nav.dyn li.open{		background:#fff;		padding-left:14px;	}	#nav.dyn li.open a img,#nav.dyn li a img{		margin:0 4px;	}

Sorry, I cannot provide the whole thing with a link. My webspace run out and am in process of searching for some new free space... Kurt

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...