ADxMenu2 - the usability script
There are situations when the drop-down multilevel menu will go outside the visible area of the page. It is either too long or has two or three sub levels (I certainly don’t recommend more than that).
Such menu is highly unusable and there are two solutions:
-
Re-arrange the layout elements so that menu fits on the page in reasonable space
-
Apply the script that will reposition the menu
Script dependencies
Calculating element position on the page is still in the art-form stage. Browser line in use today is not always up to the task. Sad thing is that you can’t check for certain element or property and be sure that script will work. Buggy or partial implementation of certain elements is the real problem. A problem that leads to ugly browser detection.
For example, Gecko browsers have complete (in terms of what I needed so far) positioning support from version 1.5 (Firebird 0.7). Previous version were fine when you used CSS-P purely. If you look at this example you will see that sub menus appear where they are supposed to.
But when you want to set the position through DOM, you have problems as illustrated in the following figure. 1.4 version of Gecko core is used by the last Netscape-branded browser (7.1) so this problem is here to stay. :(
Apple web kits prior to version 101 (I think) also have this problem, so Safari 1.0 and Omniweb suffer from it. Safari 1.2 is fine and I hope that final version of Omniweb 5 will fix this as well. Additionaly, it does not work in Opera 7.23.
Problem is that, when you do object.style.left = "0px"
, that 0 is not the (0,0)
point of the positioned parent, but that of the whole page (of body).
So, this script must check the browser version to make sure that everything would work as expected. That is one major dependence.
Another is technical. Previous version of ADxMenu was dependent on three other scripts. In this version, I removed all of them.
Onload execution
In the previous version, I used AttachEvent script to do necessary work on page load. I like that script because I know the order of onload-scripts execution. ADxMenu is not dependent on the order anymore, as the basic menu functionality is achieved using only CSS.
This entry is updated (May 6th) to be compatible with latest ADxMenu.
Therefore, I could safely use event listeners already existing in the browsers (you’ll shortly see what ADXM is).
if (window.addEventListener) {
window.addEventListener("load", ADXM.Init, false);
} else if (window.attachEvent) {
window.attachEvent("onload", ADXM.Init);
}
if (window.addEventListener) {
window.addEventListener("resize", ADXM.Viewport, false);
} else if (window.attachEvent) {
window.attachEvent("onresize", ADXM.Viewport);
}
It also acts as yet another browser detect.
DOM library
As before, I use X library from Mike Foster. Only this time I moved the functions I use to the ADxMenu script. If you use X-lib for anything else and have it already included in the page, then just delete that part of the script.
Drop-down field problem in IE/Win
You are certainly aware of the problem with form drop-down fields showing through the layers. I have recoded the menu script so that it checks for existence of WCH functions before it calls them. That way, you can include or not include the WCH script - menu script will work either way. It is good not to include it if you don’t have drop-downs or other windowed controls on the page (saves one HTTP request and some download time).
Usage
I have simplified the way script works (or so I believe). During page loading, it will create an object, ADXM
, that has certain properties and methods.
How to use it?
Include the script in the page, and add your menus with lines such as this:
ADXM.Add( "menuList", "H" );
menuList
is the ID of the main menu UL element. Second parameter defines whether main menu is horizontal (“H”) or vertical (“V”).
Update: If you are using WCH along with menu script, each UL in the menu must have an unique ID. Without the IDs, WCH will not work as expected. Kudos to Koen Calliauw for reporting this back.
How it works
All added menus will be processed on page load. Viewport size will be saved (this is also done on each resize). Then script process all menu items and adds appropriate handlers to sub menu actuators.
On hover, it calculates the position where menu should be, and then checks for available space until the bottom and right viewport edge. If there is not enough space, it moves the submenu in the opposite direction.
Take a look at the examples - follow the “full script” links. Please report any positioning problems you encounter.