![]() |
![]() |
|||||||
|
Login Change Info Logout
DOWNLOADS |
Internet Explorer 4
by Alex Hildyard
As roll-overs were the hot topic among the DHTML digerati six months ago, so, with changing fads, now the latest thing to hit the streets is site menus. A fixed, fully-expanded menu is often adequate for most small sites, and the academic difficulties inherent in creating such a menu are minimal since the menu is essentially "naïve." Its representation of directories-within-directories is a purely graphical convention, and doesn't necesarily correspond to "real" directories or the "true" structure of the site. Far more exhilarating is an outlinable "explorer-style" menu (well, perhaps "exhilarating" is not quite the term to use; we Web heads derive some strange satisfactions from our vocation!). Suffice to say that since such a menu allows its users to choose which directories to expand, it has the benefit of producing a highly economical view of the parts of one's site relevant to any particular client at any particular time. It also looks pretty good. The downside, though, is that they are often a real hassle to code, and maintaining them is a nightmare. Generating such a menu dynamically has several clear advantages. Firstly, the menu always gives an up-to-date representation of the site; secondly, it's impossible for any broken links to exist; and thirdly, by changing the HTML it generates, you could use it not only to provide navigation, but listings, in a format of your choice, of any tree structure, be that of the files on your hard drive, or an index of a hierarchical database. In designing the structure for such a menu system, a number of factors need to be taken into account:
At this point, we have to make a significant design decision, namely, which browser or set of browsers we intend to target. This is only an issue because the ability to "reveal" or "hide" elements dynamically is exclusive to Internet Explorer 4.x and Netscape 4.x. Earlier browsers simply don't have the capability to do this. A logical workaround - followed by Marcelino Alves Martins (martins@hks.com) in his freely available "Folder Tree" navigation system, is simply to reload the page each time the user causes a directory to open or close. This is fine for small directories, but can take well over ten seconds for even a moderately stocked site. I chose, accordingly, to develop a system which did not reload the page, but relied on the far quicker DHTML capabilities of Internet Explorer 4. My concession to the earlier generations of browsers is that, if you are running IE3.x or NS3.x, the menu will appear fully expanded, so you can still navigate the site, even if you don't have the benefit of being able to open and close the directories at will. The key to it all is one of IE4's "style" attribute, visibility. This can be associated with many arbitrary anchor elements, and setting it to none causes that element to disappear instantaneously, as well as causing all elements nested within that element to disappear. A moment's thought shows us that in order to accomplish our outlinable menu we will need to wrap each directory node and all the files it contains within a tag taking this style as an attribute (so that the folder is either displayed or not displayed). So long as we then recurse, following the same system, into all subnodes of that node before closing the tag, everything must work correctly. In practice this means that we need a naming system in which
I originally wrote the site menu code in C++ using STL; it did the job, but there was nothing very elegant about it, and the final code size was around 45k. Then I rewrote it in Java, which took less than half the time, was half the lines of code, and produced a 5k .class file. In future, I will stick with Java. [ View the Code ]The final code some 145 lines is generally pretty straightforward, and well peppered with comments to let you know what's going on. The only lines of much interest are those between the "script" tags in the DHTML stub. toggleVisibility is a callback function for the DOM onclick handler, and provides the functionality whereby our menu collapses and expands as you click on folders within it. The first part of the function switches the visibility attribute on all immediately descendent subfolders of the folder you click. In our naming convention these are numbered sequentially, so we simply iterate through until we can't locate any more in our document. The second part of the function toggles the visibility of the set of files within the directory you clicked, so that when you close the directory they disappear; at the same time it flips the directory folder icon from open to closed. The odd function hovCatch is a workaround for the fact that you seem to have to specify either a file or a function call as the target of an HREF, rather than inline javascript. In this case, we want our directory icons to be HREFs so that the cursor changes as it passes over them, to indicate that they are clickable. But since HREF targets get called before we get to process the onclick event, the only way that we can safely intercept that message is to make sure that the HREF does nothing. In this case, our script directs it to an empty function. On return from hovCatch, the onclick event is generated, and control passes to our custom handler just described. Deploying the Site MenuHaving compiled the source file selfIndex.java using your favourite Java 1.3 compiler, the next thing to do is to set up a few associated HTML pages. After all, a site menu isn't much use if it overwrites the menu with a new page every time you click on one of its nodes. Therefore a "targets" frame has been hardwired into the code. To use the menu, you will have to create a frameset with a target frame named "targets." <HTML> <HEAD> <FRAMESET COLS ="250,*"> <FRAME FRAMEBORDER=0 SRC="menu.htm" NAME="controls"> <FRAME FRAMEBORDER=0 SRC="" NAME="targets"> </FRAMESET> </HEAD> <BODY> </BODY> </HTML> You will probably want to save this file as the "default" document in the directory root you want to index. A default document is the document that your web server will locate and pass back automatically when a client attempt to "browse" your site, and is typically called "home.htm" or "default.htm". Next, we need to generate the site menu itself as the file "menu.htm". So simply run selfIndex.class, passing the root of the directory you want to index as a command line parameter. Note that the root itself will not be indexed, but everything beneath it. For example: jview selfIndex.class c:/websites/mySite > menu.htm Finally, you will need to create a directory named "images" which sits immediately beneath the directory you plan to index, and which must contain the images "blank.gif" (a spacer graphic of one pixel, used to align the folders), ""dirclose.gif" (closed folder), "diropen.gif" (open folder) and "file.gif" (clickable file). This gives us the final directory structure:
<dir> c:/websites/mySite
|------ home.htm
|------ menu.htm
|------ <dir> images
| |------ blank.gif
| |------ dirclose.gif
| |------ diropen.gif
| |------ file.gif
|
|------ <dir> myWebSite
|------ directories, etc.
For testing purposes, or if you only want to re-index your site periodically, you can simply run the java file, passing as a command line parameter the root of the directory you want to index, and pipe it to a .htm file. The resultant menu will index your site relative to that root, so, obviously, you must make sure that you place the resultant .htm file in the root you actually indexed, or none of the links will work. The reason for this is that it would be useless to hardcode the physical directory structure of your hard-drive into a menu if you ever wanted to deploy it on a remote site. More probably, however, you will want to run the menu with some degree of automation, so that it regenerates itself as clients access your site. This way you can carry on updating your site without taking it offline, and the worst that can happen is that a few pages have duff links before an existing client reloads your home page. The easiest way to do this is via Perl, but since my site was running IIS, I chose to invoke the program via ASP, using Stephen Genusa's free redistributable, ASPEXEC.DLL (which you can download from www.genusa.com). This gives you, among other things, the ability to run a Windows executable on the server and pipe whatever it sends to stdout back to the client as an HTML file. In this case, that executable was simply: jview selfIndex.class and I adapted my frameset so that instead of opening "menu.htm" it opened "menu.php", which contained the ASP script:
<%
Set Executor = Server.CreateObject("ASPsvg.Execute")
Executor.Application = Server.MapPath( "/" ) & "jview selfIndex.class"
Executor.Parameters = Server.MapPath( "/" )
Executor.ShowWindow = false
strResult = Executor.ExecuteDosApp
Response.Write strResult
%>
On opening the frameset, the ASP script executes, streaming the dynamically generated menu to stdout. This is then returned straight to the client in the form of an HTML page. Alternatively, if you want to go down the COM route and develop your own component to drop into ASP via the CreateObject method, it's a breeze to write a minimal ActiveX or ATL component that simply calls the "C" runtime library _system command and returns output via a BSTR. Or, again, it's trivial to add COM wrappers to a Java project calling Runtime.exec in either Symantec Cafe or Visual J++ (particularly so with VJ6). But if your site isn't running one of Microsoft's IIS-enabled solutions, it's almost certainly easiest just to stick with Perl. Further DirectionsWhile writing this, something I wanted to incorporate into my menu was the idea of file and directory aliasing. One might, for example, embed some custom tag (like <FNAME>) in one's HTML documents, which the self-indexer would then take as the string to display for that file in the menu. For example, "default.htm" might be aliased to the "friendly" name: "It all starts here . . ." For a start, this would help abstract the site developer from the end user. Secondly, in a more complex system, these aliases could be real, cross-referenced by an ASP in a database. This way, one's site would have added security, since the site menu would never access actual HREFs, but only aliases to them (making it impossible for a client to know the real location of the file he was looking at). It would also be potentially more maintainable, since pages could be radically re-written while maintaining their original aliases, and, conversely, aliases could be changed at will without altering the underlying content to which they referred. The main reason I didn't implement this was that searching every document on a site every time a user logged into that site is likely to reduce most servers to a gibbering wreck. However, there are workarounds; for example, one might be to re-index the alias list only once a day. Remember, too, that rather than simply running the site indexer once when a user visits your homepage, you could run it each time he or she moves onto another page, thereby providing a dynamic map of "information accessible from this page."
|
|
|
|||||||||||||||||||||||
|
Questions or Comments? devcentral AT iticentral DOT com PRIVACY POLICY |