Using ASP and XML to make menu navigation system

Source: Internet
Author: User
Tags define end eval functions variables string version variable
xml| Menu | Navigation 1. 1 overview
The efficient use of limited space on Web pages is not easy, especially when it comes to arranging a large number of links on a page. How can you organize various links to make room for other important content? Is it a one-time display of all the links, or is it divided into multiple pages to hide them deeply? Both of these methods are not ideal, obviously. With DHTML, we can keep enough page space for other content while providing users with quick and easy access to links.
This paper introduces the implementation of a menu system. This menu is similar to the Windows Start menu, and users can access all the links with just one click of the mouse. The contents of the menu are defined by the XML document and the client behavior is implemented by DHTML. Parsing of XML documents is done on the server side, so it is not required to support XML for user browsers.

The next section of this article details its implementation, including the structure of the XML document and how to parse the XML document and construct the final menu with the client JavaScript.
1. 2 Static and dynamic
Dynamic generation of page content refers to the dynamic (automatic) generation of content when a user requests it, while static content saves the auto-generated content as a file, which is sent to them when the user requests it. Some readers have written about this issue, and we have forwarded readers ' letters and discussed their views in the "re-discussion of the publication of Web content--separating content and design with XML and ASP."
Depending on the actual size of the menu and how frequently the menu content changes, some times you may not want the menu to be dynamically generated. At this point, you can make the menu code static: Run the script described in this article, save the generated menu HTML code as a containing file and refer directly to it. If you can adopt this scenario, it will save a lot of valuable server resources.
This article takes the dynamic menu as an example to introduce the realization principle. However, in order to facilitate the reader, in the download package we provide two versions of the server script, respectively, for the dynamic generation of menus and generate static menu HTML code. When using a static version, open the Xmlcreatemenu_entry.asp page and enter the following two messages: The first is the XML file used, and the second is the path to the containing file, which will save the HTML-formatted menu code. When you enter this information, you can automatically run the server script to generate the menu code. Later, if you want to change the menu content, just modify the XML file, and then repeat the above process.
When using static menus, refer to the dynamic menu usage in the default.asp of this article by simply default.asp the <!--#include file= "xmlcreatemenu_dynamic.asp"-> Change to include a static menu file.
1. 3 Data structure
XML is undoubtedly one of the most popular topics at the moment, and it is widely believed that the future web lies in XML. However, this article uses XML to define menu content not for the sake of fashion, where XML does have special benefits.
First of all, since the menu system is used, it is unlikely to be used only on brilliantly pages, which are often used in the same menu for all pages of the entire site. This requires the ability to quickly construct menus and minimize the time spent accessing the menu definition data. Second, the menu is a hierarchical structure, and the data that defines the content of the menu is best also hierarchical. This is not only a convenient way to reflect the dependencies between menu items (and thus facilitate modification), and we can see from the end of this article that it is quite convenient to use recursive functions to analyze hierarchical data.
XML can meet both requirements, not only for fast data access (no additional network connectivity, no need to log in to the database, etc.), but also for XML to describe the hierarchical structure of the data very naturally. In addition, as we mentioned earlier, parsing XML documents is done on the server side, so the user's browser is not required to support XML.
You can edit an XML document using both a plain text editor and a number of dedicated XML editors to choose from, see the Concise XML tutorial, and see XML Tools for a description of this and the basic concepts of XML.
The first step in creating a menu system is to define the menu contents in an XML document. After considering several possible approaches, we decided to take the simplest approach, making it easier for readers who are unfamiliar with XML to understand and change the XML file. Each menu item contains at least two data, which is the text and link of the menu item, and can be easily added to a child node if it has more than one submenu. To maintain the simplicity of the entire system, menus must not exceed three floors. The following is a fragment of the XML file in this article.
< MenuItem >

< hyperlink/>

< name > Entertainment </name >

< MenuItem >

< HyperLink >Link1.asp
< name > Game </name >

</menuitem >

< MenuItem >

< HyperLink >link4.asp
< name > Auto/motorcycle </name >

</menuitem >

</menuitem >
Each menu item is defined by a < MenuItem > tag, which has at least two child nodes: the child node < hyperLink > defines the link for the menu item, and the < name > contains the text of the submenu.
As you can see, the first < HyperLink > in the previous code did not give a link because the menu item was used to pop up the submenu and it doesn't point to any specific Web page. The child nodes are defined in the same way as the parent node definition method, using the < MenuItem > tag. This hierarchy can be nested all the time, but we have mentioned that the nesting level should not be excessive, and the sole purpose of the menu system should be to facilitate user access, rather than make access more difficult. 2. 1 Traversing the XML tree
After the menu content is defined in the XML document, the next task is to traverse and analyze the data in these hierarchies, and to generate the HTML code for the menu. This is achieved mainly through a recursive function walktree. The efficiency of this part of the code is very important and you cannot allow users to wait too long to generate a menu.
Before calling the recursive function Walktree, we first need to find the root of the XML document. This root can be obtained using the following code (complete code, download from the end of this article):
var xmlroot = xmldoc.documentelement;
After you get the root of the document, the program then creates an array that describes the hierarchical relationship between the menu items. As the following code shows, this array is dynamically named as the JavaScript eval function. Variable StartMenu determines the basic part of the full menu name, and we can see from the back of this article that the client code also uses the menu name to activate the menu.
var image = "< img align=right vspace=2 height=10

width=10 border=0 src= ' http://www.webjx.com/htmldata/2005-02-25/images/tri.gif ' > ';

var currentnode = "";

var newNode = "";

var currentmenu = "";

var startmenu = "Menu1";

var level = 1;

var arrayholderarray = new Array ();

var arraynamesarray = new Array ();

var tempstring = "";

 

The name of the array is the div name plus "_array"

Eval ("var" + StartMenu + "_array = new Array ()")

for (var i=0;i< xmlroot.childnodes.length;i++) {

CurrentNode = XMLRoot.childNodes.item (i);

if (currentnode.haschildnodes () = = True && currentNode.childNodes.length >1) {

Currentmenu = StartMenu + "_" + (i+1);

Thismenu = StartMenu;

if (CurrentNode.childNodes.length >2) {

Smenuitem = Escape ("< SPAN id=" "+ Thismenu +" _span "+ (i+1) +

"Class= ' Celloff ' +

Currentmenu + "', this," + Level +

")" > "+

Image + CurrentNode.childNodes.item (1). Text +

"</span >< BR >

");

Eval (StartMenu + "_array[i] = Smenuitem")

Walktree (CurrentNode)

} else {

Smenuitem = Escape ("< SPAN id=" "+ Thismenu +" _span "+ (i+1) +

"" Class= ' Celloff ' "+

" +

Level + ")" "+

" +

CurrentNode.childNodes.item (0). Text + "' >" +

CurrentNode.childNodes.item (1). Text +

"</span >< BR >

");

Eval (StartMenu + "_array[i] = Smenuitem")

}

}

}
After the initial array is created (named Menu1_array), the program checks whether the first < MenuItem > tag contains child nodes. To get the number of child nodes is very simple, you can only access the parent node's Childnodes.length property.
When checking the number of child nodes, the criterion is whether the Childnotes.length property is greater than 1 because the text in the node is also a node and the length value contains it. If the criterion is equal to 1, even if the only child node is a text node rather than an element node, the IF statement returns True (although we can also examine the subtype of the child node, but not as concise as the current method).
While parsing the node, all the required < DIV > attributes and the client event response code (text) are saved to the variable Smenuitem, while the Smenuitem is saved to the array, where the position in the array is determined by the current position in the loop. If the current node contains child nodes of the element type, call Walktree () and pass the current node as a parameter to it.
2. 2 recursive function Walktree
The so-called recursive function, is to call their own functions. Recursive functions are ideal for processing data in a hierarchical structure. When traversing an XML tree, recursive functions can be used to reduce a lot of code, and a simple recursive structure can handle a large number of submenus.
The Walktree () function takes a node as a parameter, similar to the procedure discussed earlier, which creates an array and examines the Childnode.length property. Here is the complete code for Walktree ():
function Walktree (node) {

level = 1;

Array name is the name of the Div plus "_array"

Eval ("var" + Currentmenu + "_array = new Array ()")

for (var j=2;j< node.childnodes.length;j++) {

NewNode = Node.childNodes.item (j)

if (newnode.haschildnodes () = = True && newNode.childNodes.length >2) {

Each node has 0 = link and 1 = text node

So if you have only these subnodes, you don't have to call the function again

Currentmenu = Currentmenu + "_" + (j-1);

Thismenu = currentmenu.substring (0,currentmenu.length-2);

Smenuitem = Escape ("< SPAN id=" "+ Thismenu +" _span "+ (j-1) +

"" "Class= ' Celloff '" + "+ Currentmenu +

"', this," + Level + ")" > "+

Image + NewNode.childNodes.item (1). Text +

"</span >< BR >

");

Eval (Thismenu + "_array[j-2] = Smenuitem");

Walktree (NewNode);

} else {

Smenuitem = Escape ("< SPAN id=" "+ Currentmenu +" _span "+

(j-1) + "" class= ' Celloff ' "+

" +

Level + ")" "+

" +

NewNode.childNodes.item (0). Text + "' >" +

NewNode.childNodes.item (1). Text +

"</span >< BR >

");

Eval (Currentmenu + "_array[j-2] = Smenuitem");

}

}

Arraynamesarray[arraynamesarray.length] = Currentmenu;

TempString = (unescape (eval (currentmenu + "_array.join (")))

Arrayholderarray[arrayholderarray.length] = tempstring

 

Currentmenu = currentmenu.substring (0,currentmenu.length-2);

End Function returns previous menu item

level = 1;

}
If a child node can be found, the function calls itself with the current node as the parameter. Each time the function calls itself, the corresponding array and Smenuitem variables are generated. The name of the current menu is saved by the variable Currentmenu, and a new name is saved in the Thismenu, which allows the program to easily find the hierarchical relationship between the menu items, which we can see later in the client script.
Please read the end of the Walktree () function carefully. The Arraynamesarray array created in the preceding code is used to hold the name of the menu, and then the variable tempstring gets all the array information for the current node and organizes it into a string. This string is added to another array named Arrayholderarray. The purpose of the array Arraynamesarray is to save the name of the menu item, and to put the menu item (and its subordinate submenu items) into < div >, all of the < div > area will refer to the contents of the Arraynamesarray. The array Arrayholderarray saves all the information that will be written to each < DIV >, including the name of the menu item, the link, and the event information for the client script.
The relationship between these arrays looks a bit complicated at first, and careful observation is not difficult to understand. The Walktree function uses these arrays to do a lot of work within a small amount of code.
Once you've prepared the array, you can then write < DIV > and their contents to the Web page. The following code is responsible for this part of the work (see xmlcreatemenu_dynamic.asp).
Flip the array to form the correct < DIV > order

Arrayholderarray.reverse ()

Arraynamesarray.reverse ()

Iterate through arrays, output < DIV > tags, and code for individual menu items

for (i=0;i< arraynamesarray.length;i++) {

Response.Write ("< div id= '" + arraynamesarray[i] + "' class= ' Clsmenu ' >");

Response.Write (Arrayholderarray[i]);

Response.Write ("</div >

");

}
Why do you want to flip the order of the arrays? In short, it will simplify our future operations. After flipping, the < div > area of the program output is ordered by the top submenu in the hierarchy and the last Face menu, or after the array is flipped, the < DIV > area is guaranteed to have the correct order in the z-axis direction. If you still can't grasp it all at once, take a look at the following picture, which is the menu effect after commenting on the two reverse method calls:

After the array is flipped, the < DIV > tag and its contents are then output. As mentioned earlier, the,< div > Zone's name is determined by the array Arraynamesarray,< div > area is determined by the array Arrayholderarray. The following code is a fragment of the previous code output < div > area, and the other < div > areas are very similar:
< div id= ' menu1 ' class= ' Clsmenu ' >

< span id= "Menu1_span1"

class= ' Celloff '

     

     

> Home

</span >< br >

< span id= "menu1_span2"

class= ' Celloff '

     

>

< img align=right vspace=2 height=10

width=10 border=0 src= ' http://www.webjx.com/htmldata/2005-02-25/images/tri.gif ' > Leisure

</span >< br >

</div >

The Xmlmenuscript.js file contains all the JavaScript code that supports the client menu action. Variables defined earlier in the file can be used to customize the display color of a menu item under various states (checked or unchecked), as described in Xmlmenuscript.js. It should be explained that, in the current implementation, client script code requires running in IE version 4 or above. If you want the menu to support Netscape browser at the same time, this part of the code should be modified accordingly.
The menu system starts when the user clicks a link (such as the "Web site" in this article). The HTML code for the Startup menu looks like this:
< A id= "Start" >

< >< FONT color= "#FFFFFF" > website </font ></b >

< IMG src= "http://www.webjx.com/htmldata/2005-02-25/images/yellow_arrow_down2.gif" width= "height=" border =0 >

< a >
The Startit () function specified in the OnClick event has three parameters: the menu name, a reference to the link itself, and a menu hierarchy. Because the menu system is started at this time, the specified level is 0.
Although one page can have more than one menu, there is only one menu visible at any time. The Startit () function checks whether the menu has been activated. If it is not activated, the following statechange () function is called. In addition, Startit () must also hide the HTML < SELECT > elements and Java applets (see the implementation code for Startit () if present) while the menu is active.
function StateChange (menu,thisitem,level) {

menu = Menus to be displayed, thisitem= the current menu item < SPAN >

Level= Menu Nesting level

  

The menu item that the mouse points to changes, changes the high brightness state

if (currentspanelement!= thisitem.id && started!= true) {

This line of code is only useful for the first time you enter

if (currentspanelement = = "") currentspanelement = thisitem.id;

Eitemold = eval ("document.all (' + currentspanelement + ')");

Eitemnew = eval ("document.all (' + thisitem.id + ')");

Eparent = eitemnew.parentelement;

div background color must be set, otherwise the default is transparent

EParent.style.background = Offcellcolor;

    

Remove the high brightness color of the previous Mouse stop menu item

EItemOld.style.background = Offcellcolor;

EItemOld.style.color = Offtextcolor;

Highlight a newly selected menu item

EItemNew.style.background = Oncellcolor;

EItemNew.style.color = Ontextcolor;

Track where the last mouse stays

Currentspanelement = thisitem.id;

}

  

if (menu!= "") {

Emenu = eval ("document.all (' + menu + ')");

Eitem = eval ("document.all (' + thisitem.id + ')");

Hidediv (level);

Track a menu that has been opened (displayed)

Menuarray[menuarray.length] = menu;

var Positionx = EItem.parentElement.offsetLeft +

Offsetmenux + document.body.scrollLeft;

var positiony = EItem.parentElement.offsetTop +

Eitem.offsettop + Offsetmenuy + document.body.scrollTop;

if (started) {

Positionx = Clickx + Startdistancex + document.body.scrollLeft

Positiony = clicky + Startdistancey + document.body.scrollTop

}

If the screen is not wide enough, move the menu display position to the left

if ((Positionx + emenu.offsetwidth) >= document.body.clientWidth) {

Positionx-= (Emenu.offsetwidth * 1.3);

Positiony + 15;

}

If the menu position is left, move right

if ((Positionx + emenu.offsetwidth) < = emenu.offsetwidth) {

Positionx + + (Emenu.offsetwidth * 1.3);

}

If the menu is down, move the menu up so that it is aligned at the bottom and the bottom of the browsing window

if ((Positiony + emenu.offsetheight) >= document.body.clientHeight) {

If (started!= true) Positiony = Document.body.clientheight-emenu.offsetheight;

}

EMenu.style.left = Positionx;

EMenu.style.top = Positiony;

If you don't flip the array in ASP script, use this line of code

EMenu.style.zIndex = level;

emenu.style.visibility= ' visible ';

}

Menu already displayed

started = false;

}
The StateChange () function has three parameters: the menu name, the < SPAN > element of the current menu item, and the hierarchy. If the user selects a different < SPAN > element (menu item), StateChange () changes the background and text color of the menu item, while changing the status of the previously selected menu item. In addition, StateChange () is also responsible for invoking other functions to hide the menu and to modify the location of the menu when the menu location is not appropriate.
The style used by the menu in Menustyle.css, modify the file to adjust the appearance of the menu.
Please download this article code here, 8 K.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.