This example shows the use of tree menus, using JavaScript and Ajax to load (html page only) . The nodes with child nodes will expand

Step: 1 Create web site http://manas6/aspnet.35/mm.AjaxCollapsibleMenu1B/Default.aspx

 

Step: Code

majax.js

///this toggleing menu is modified from The JavaScript Anthology 101 Esential Tips ,Tricks & Hacks
//Publisher SitPoint
//as there was a dubious Notice of Rights, only theme and idea are taken
// Chapter 15 : page 363
var details = false; var isreset = false; var doc = false; var number = 0;
//// FireFox and Opera, this functions will not be displayed in
// doc.innerHTML +=
function treeMenu(navid, indexpage) {
doc.innerHTML += "<br/> treeMenu(navid, indexpage) nvid "+ navid + " -- indexpage " + indexpage.toString();
if (typeof document.getElementById == 'undefined') { return; }
var rollover = new Image;
rollover.src = 'down-red.gif';
rollover = new Image;
rollover.src = 'minus.gif';
// get the element using DOM
var tree = document.getElementById(navid);
if (tree) {
var items = tree.getElementsByTagName('li');
for (var i = 0; i < items.length; i++) {
treeTrigger(tree, items[i], navid);
}
if (navigator.vendor == 'Apple Computer, Inc.'
|| typeof window.opera != 'undefined') {
resetNodes(tree);
}
resolveBrowser(tree, navid, indexpage);
}
number++;
}
//// In FireFox and IE, this functions will be displayed in
// Opera will not display any resutl in
// doc.innerHTML +=
function resetNodes(tree) {
var menus = tree.getElementsByTagName('ul');
doc.innerHTML += "<br/>resetNodes(tree) " + menus;
for (var i = 0; i < menus.length; i++) {
if (menus[i].style.position != 'static') {
menus[i].style.display = 'none';
}
menus[i].style.position = 'static';
}
isreset = true;
}
// only IE will add result in
//doc.innerHTML +=
function treeTrigger(tree, li, navid) {
doc.innerHTML += "<br/>treeTrigger(tree, li, navid)" + li.toString();
var a = li.getElementsByTagName('a')[0];
var menu = li.getElementsByTagName('ul').length > 0
? li.getElementsByTagName('ul')[0] : null;

if (menu) {
li.className += (li.className == '' ? '' : ' ') + 'hasmenu';
}

li.onclick = function(e) {
var target = e ? e.target : window.event.srcElement;
while (target.nodeName.toUpperCase() != 'LI') {
target = target.parentNode;
}
if (target == this && isreset) {
if (menu) {
if (menu.style.display == 'none') {
clearSiblingBranches(this);
menu.style.display = 'block';
a.className += (a.className == '' ? '' : ' ') + 'rollover';
}
else {
menu.style.display = 'none';
a.className = a.className.replace(/ ?rollover/g, '');
}
return false;
}
else {
return true;
}
}
};

attachEventListener(a, 'keyup', function(e) {
if (!isreset && e.keyCode == 9) {
resetNodes(tree);
}
}, false);

var moves = 0;
attachEventListener(a, 'mousemove', function() {
if (!isreset) {
moves++;
if (moves > 2) { resetNodes(tree); }
}
}, false);
}
// All the Browsers will add results
function clearSiblingBranches(trigger) {
doc.innerHTML += "<br/> clearSiblingBranches(trigger)";
var menus = trigger.parentNode.getElementsByTagName('ul');
for (var i = 0; i < menus.length; i++) {
menus[i].style.display = 'none';

var a = menus[i].parentNode.getElementsByTagName('a')[0];
if (a) {
a.className = a.className.replace(/ ?rollover/g, '');
}
}
}
// Only IE will display the result
function resolveBrowser(tree, navid, indexpage) {
var page = document.location.href;
doc.innerHTML += "<br/> resolveBrowser(tree, navid, indexpage)" + tree + navid + indexpage;
page = page.replace(indexpage, '').replace(/,/g, '%2C');

var links = tree.getElementsByTagName('a');
var matches = [];
for (var i = 0; i < links.length; i++) {
var href = links[i].href;
if (href && !/[a-z]+\:\/\//.test(href)) {
matches = [];
break;
}

href = href.replace(indexpage, '').replace(/,/g, '%2C');
if (href != '' && page.indexOf(href) != -1) {
matches[matches.length] = links[i];
}
}
if (matches.length < 1) { return; }

var probabilities = [];
for (i = 0; i < matches.length; i++) {
href = matches[i].href;
probabilities[i] = [0, href];

for (var j = 0; j < href.length; j++) {
if (href.charAt(j) == page.charAt(j)) {
probabilities[i][0]++;
}
}
}

probabilities.sort(compare);
href = probabilities[0][1];

for (i = 0; i < links.length; i++) {
if (links[i].href == href) {
previousPage(links[i], href, navid);
break;
}
}
}
// Only IE will display while refreshing the page.
function compare(a, b) {
doc.innerHTML += "<br/> Compare" + a + "--: -- "+ b;
return b[0] - a[0];
}
// Only IE will display while refreshing the page.
//The previous menu will remain expanded in IE (contrast to Opera, Fire Fox)
//
function previousPage(link, href, navid) {
doc.innerHTML += "<br/> previousPage(link, href, navid)" + link + href.toString() + navid;
link.className += (link.className == '' ? '' : ' ') + 'rollover';

var li = link.parentNode;
var menu = li.getElementsByTagName('ul').length > 0
? li.getElementsByTagName('ul')[0] : null;

if (menu) {
menu.style.display = 'block';
menu.style.position = 'static';
}

var text = (link.getAttribute('title') && link.title != '')
? link.title : link.firstChild.nodeValue;

link.title = text + (link.href == href
? ' [you are here]' : ' [you\'re in this section]');

if (li.parentNode.id != navid) {
link = li.parentNode.parentNode.getElementsByTagName('a')[0];
previousPage(link, href, navid);
}
}

function attachEventListener(target, eventType, functionRef, capture) {
doc.innerHTML += "<br/> attachEventListener(target, eventType, functionRef, capture)";
if (typeof target.addEventListener != 'undefined') {
target.addEventListener(eventType, functionRef, capture);
}
else if (typeof target.attachEvent != 'undefined') {
target.attachEvent('on' + eventType, functionRef);
}
else {
eventType = 'on' + eventType;

if (typeof target[eventType] == 'function') {
var oldListener = target[eventType];

target[eventType] = function() {
oldListener();

return functionRef();
}
}
else {
target[eventType] = functionRef;
}
}

return true;
}
// http://www.tek-tips.com/faqs.cfm?fid=4862
// FireFox and Opera, this functions will be displayed in
// doc.innerHTML +=
function addOnloadEvent(fn) {
doc.innerHTML += "<br/> addLoadListner(fn)";
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('load', fn, false);
}
else if (typeof document.addEventListener != 'undefined') {
document.addEventListener('load', fn, false);
}
else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onload', fn);
}
else {
var oldfn = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
}
else {
window.onload = function() {
oldfn();
fn();
};
}
}
}
// http://www.tek-tips.com/faqs.cfm?fid=4862
//// FireFox and Opera, this functions will be displayed in
// doc.innerHTML +=
//this function will fire first, and will be registered in IE 8.0
addOnloadEvent(function() {
doc.innerHTML += "<br/>addOnloadEvent(function() fired";
treeMenu('ulNodes', 'Default.aspx'); });
// page loader starts
var xmldoc = false;
var links = document.getElementsByTagName("span");
var details = false;
function getHTTPObject() {
var ajaxObject = false;
doc.innerHTML += "<br/> getHTTPObject() fired ";
if (window.XMLHttpRequest) {
ajaxObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
ajaxObject = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
ajaxObject = false;
}
}
}
return ajaxObject;
}

function grabFile(file, divx) {
//divx parameter will target the div1 or div2 as sent as an argument.
var request = getHTTPObject();
doc.innerHTML += "<br/>grabFile(file, divx) fired ";
details = document.getElementById(divx);
if (request) {
request.onreadystatechange = function() {
parseResponse(request);
}
request.open("GET", file, true);
request.send(null);
}
}

function parseResponse(request) {
doc.innerHTML += "<br/>parseResponse(request) fired " ;
if (request.readyState == 4) {
if (request.status == 200 || request.status == 304) {
//details = document.getElementById("sp1");
//alert(details);
details.innerHTML = request.responseText;
}
}
}

window.onload = function() {
details = document.getElementById("sp1");
details;
doc = document.getElementById("showLoad");
doc.innerHTML = "";
doc.innerHTML = "<br/> window.onload = function(): Fired";

}

main.css

/* structural styles and offsets */
.base { left:5px; font-size:12px; padding-left:10px;}
/* handles div and span*/
body { background-color:Gray; }
#sp1 {
width :548px; background-color: #FFFFCC; left:240px;
position:absolute; height:80%; padding-left:10px; top:10px;border: 2px solid #000080;
}
#div1 { width: 220px;background-color: #FFFFCC; }
#leftPanel
{
width:220px; border: 2px solid #000080;background-color: #FFFFCC; position:absolute; height:80%;
}
#showLoad
{
top:300px; z-index:1; position:absolute; padding-left:10px; color:Navy;
font-size:12px; width: 50%; height: 400px; background-color:#FFFFCC; overflow:scroll;

}
/* toggling tree list */
ul.CollasingNodes, ul.CollasingNodes li, ul.CollasingNodes ul {
clear:both;
margin: 0;
padding: 0;
list-style-type: none;
font-size: 100%;
}

ul.CollasingNodes {
position: relative; cursor: default; width: 8.2em; margin: 2px 0 0 5px;
}

ul.CollasingNodes li {
position: relative;
text-align: left;
cursor: pointer;
cursor: hand;
width: 8.2em;

}

ul.CollasingNodes ul {
cursor: default;
width: 8.2em;
padding: 2px 0;
position: absolute;
left: -100em;
margin: 0 0 0 1em;
}

ul.CollasingNodes ul li {
width: 8.2em;
}


/* design styles */
ul.CollasingNodes a:link, ul.CollasingNodes a:visited {
display: block;
cursor: pointer;
cursor: hand;
padding: 1px 0 1px 15px;
font: 0.7em tahoma, verdana, sans-serif;
color: Navy;
text-decoration: none;
letter-spacing: 1px;
}

ul.CollasingNodes a:hover, ul.CollasingNodes a:focus, ul.CollasingNodes a:active {
text-decoration: underline;
color: red;
}


/* plus/minus icons */
ul.CollasingNodes li.hasmenu > a:link, ul.CollasingNodes li.hasmenu > a:visited {
background: url(plus.gif) no-repeat 1% 50%;
}

ul.CollasingNodes li.hasmenu > a.rollover:link,
ul.CollasingNodes li.hasmenu > a.rollover:visited {
background: url(minus.gif) no-repeat 1% 50%;
}

* html ul.CollasingNodes li.hasmenu a:link,
* html ul.CollasingNodes li.hasmenu a:visited {
background: expression(/hasmenu/.test(this.parentNode.className)
? "url(plus.gif) no-repeat 1% 50%" : "solid");
}

* html ul.CollasingNodes li.hasmenu a.rollover:link,
* html ul.CollasingNodes li.hasmenu a.rollover:visited {
background: expression(/hasmenu/.test(this.parentNode.className)
? "url(minus.gif) no-repeat 1% 50%" : "transparent");
}


/* browser hacks *
http://www.w3.org/TR/CSS21/media.html
for desktops
/
For example, in the following snippet, the rule on the P element applies in 'screen' mode (even though the '3D' media type is not known).

@media screen, 3D {
P { color: green; }
}

@media screen, projection {
* html ul.CollasingNodes li {
display: inline;
float: left;
background: #fff;
}
}
*/

 

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<title></title>

<link rel="stylesheet" type="text/css" href="main.css" />

</head>
<body>
<span id="sp1">This application has limitation. You can load html pages without any problem
However, if you try to load load a server page like home.aspx, it will generate a runtime error.<br/><font color='red'> Further,menus may load slower</font>
In the browsers like FireFox and Opera,
</span>
<span id="showLoad"></span>
<form id="form1" runat="server">
<div id="leftPanel">
<div id="div1" >

<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/scripts/majax.js" />
</Scripts>
</asp:ScriptManager>


<a class="base" href="Default.aspx" >Home :Base Camp</a>

<ul id="ulNodes" class="CollasingNodes">
<!-- root 1 start here -->
<li><a href="/Root:1.1/"> Root: 1.1</a>
<ul>
<li><a href="/Root:1.1.1/">Root:1.1.1</a>
<ul>
<li><a href="/Root:1.1.1.1/">Root: 1.1.1.1</a>
<ul>
<li><a href="/expand/" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" > page_1.htm</a>
<ul>

<li><a href="#" onclick="grabFile('index_files/option_2.aspx', 'sp1'); return false;" >Option-2 </a></li>
<li><a href="#" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" >page_1</a></li>
<li><a href="#" onclick="grabFile('index_files/option_2.htm', 'sp1'); return false;" >page_2</a></li>
<li><a href="#" onclick="grabFile('index_files/option_3.htm', 'sp1'); return false;" >page_3</a></li>
<li> <a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a> </li>
</ul>
</li>
<li><a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a></li>
</ul>
</li>
<li><a href="/Root: 1.1.1.2/">Root: 1.1.1.2</a>
<ul>
<li><a href="/expand/" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" > page_1.htm</a>
<ul>

<li><a href="#" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" >page_1</a></li>
<li><a href="#" onclick="grabFile('index_files/option_2.htm', 'sp1'); return false;" >page_2</a></li>
<li><a href="#" onclick="grabFile('index_files/option_3.htm', 'sp1'); return false;" >page_3</a></li>
<li> <a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a> </li>
</ul>
</li>
<li><a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="/products/">Root:1.1.2</a>
<ul>
<li><a href="/expand/" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" > page_1.htm</a>
<ul>

<li><a href="#" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" >page_1</a></li>
<li><a href="#" onclick="grabFile('index_files/option_2.htm', 'sp1'); return false;" >page_2</a></li>
<li><a href="#" onclick="grabFile('index_files/option_3.htm', 'sp1'); return false;" >page_3</a></li>
<li> <a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a> </li>
</ul>
</li>
<li><a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a></li>
</ul>
</li>
<li><a href="/manufacture/">Root: 1.1.3</a>
<ul>
<li><a href="/home/" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" > page_1.htm</a>
<ul>

<li><a href="#" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" >page_1</a></li>
<li><a href="#" onclick="grabFile('index_files/option_2.htm', 'sp1'); return false;" >page_2</a></li>
<li><a href="#" onclick="grabFile('index_files/option_3.htm', 'sp1'); return false;" >page_3</a></li>
<li> <a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a> </li>
</ul>
</li>
<li><a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a></li>
</ul>
</li>
</ul>
</li>
<!-- root 2 start here -->
<li><a href="/Root.1.2/">Root 1.2</a>
<ul>
<li><a href="#" onclick="grabFile('index_files/option_1.htm', 'sp1'); return false;" >page_1</a></li>
<li><a href="#" onclick="grabFile('index_files/option_2.htm', 'sp1'); return false;" >page_2</a></li>
<li><a href="#" onclick="grabFile('index_files/option_3.htm', 'sp1'); return false;" >page_3</a></li>
<li> <a href="#" onclick="grabFile('index_files/option_4.htm', 'sp1'); return false;" >page_4</a> </li>

</ul>
</li>
</ul>
</div>
</div>

</form>

</body>
</html>
 

Step: 3 Runtime analysis

Same with IE 8.0