Aleksandar • Vacić

iOS bits and pieces

ADxMenu v4 - flyout (drop-down) menu

v4 is online for some time now and people have already used it. This version is the result of the months and months of experience implementing previous version on all kinds of web sites.

I have changed the basic CSS, but just a bit, mainly simplified it. Important changes from the v3 are:

  1. Completely clean HTML inside the menu - there are no classes, no IDs

  2. Behavior component (.htc) is not used anymore - it uses plain Javascript

  3. Instant execution of the IE script, thus making the menu usable even before the entire page content is downloaded

  4. WCH is not part of the script, but it uses it if it’s available You must include WCH.js before the ADxMenu.js for this to work

  5. li:hover is not simulated automatically, you must write the CSS yourself, using adxmhover class

  6. Submenu opening now gives you certain degree of freedom - they will not disappear if you move the mouse slightly off the submenu

  7. Much, much quicker in IE than v3

The most important improvement is certainly the last one. I wrote 1.5 years ago about the speed issues of the ADxMenu v3. The good thing about the .htc-based version is great CSS ease of use; bad thing: only usable for small menus. I posted a quick JS-based fix back then, but it was applicable only in controlled cases. For longer menus it was simply not good enough, and usability is what counts in the end. This version is speed beast.

This new version is simplification effort. I have gave up on the “ultimate”, “enterprise” and similar adjectives. From the implementation questions I receive on the daily basis, I realized that it’s not really possible to make it work in like 1-2-3, for all people and for all cases. Thus, the clean-up.

The cleanest HTML you can imagine

The basic CSS and the script require no IDs and no classes inside the menu body. The only thing required is that you put class="adxm" on the main ul element and that’s it. In browsers supporting li:hover and li>ul selectors, that is all that’s needed.

Obviously, if you have more than one menu on the page, then you would use something like: class="menutop adxm" and class="sidemenu adxm".

Any other classes and IDs you add can be used to implement complicated designs, icons or whatever.

Javascript for IE6

If you look at the source code of the examples, you will see how easy is to add it:

[code]

[/code]

What does it do? It looks for all ul elements with the class of adxm. Then for each of them fetches all li elements and looks for those that have nested lists. It attaches the following two event handlers on matched li elements:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// li:hover

oLI.onmouseenter = function() {

  this.style.position = "relative";

  this.className += " adxmhover";

};

//   li:blur

oLI.onmouseleave = function() {

  this.style.position = "static";

  this.className = this.className.replace(/adxmhover/,"");

};

The newly created class can then be used to replicate the :hover and the child selector, in the following manner:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.adxmhover ul,

.adxmhover .adxmhover ul {

  visibility: visible;

}



.adxmhover li ul,

.adxmhover .adxmhover li ul {

  visibility: hidden;

}

Easy peasy.

Why the position setting? It’s a well known fact that IE6 has faulty implementation of positioning context stacking. That leads to huge problems, one of which is illustrated in the short example I mocked up, where that line is deleted from the script. Using this line, only the currently hovered item has the position set to relative and thus there are no problems with context stacking.

Speed daemon

Consequence of this positioning trickery is that IE is constantly re-rendering the page, since position:relative changes the position of the nested submenu. This is the major source of the speed issues in IE, when mouse is quickly moved up/down on the large menu. Take a look at the example using old .htc-based code, in IE (you can witness the freeze at the start of the page while .htc works). Hover any item in left-hand menu, for instance soccer or horse racing. Then move the mouse up and down - IE will visibly lag behind your movement. When looked in Firefox, all is breeze, as they implement context stacking properly and do not require this position trickery.

And now look at the same page design, same menus, but using v4. Repeating the test from above, you can see that everything is breeze in IE too.

Usability

The advantage no.3 from the list at the post start. Huge usability improvement, especially on large, heavy pages. Having the script executing practically immediately after .html page downloads, without the wait on flash files, videos, images - this is my second favourite feature of the new version. I have prepared the example that demonstrates this - menu is working in IE before the image has finished downloading. You people with those damn fast internet links might not even notice this, if the image downloads in few secs. We, ones with cheaper tickets, have no such “problem”.

All thanks goes to Dean Edwards, Matthias Miller and John Resig, plus Rob Cherny for a lovely script I use.

Onmouseenter, onmouseleave

These two event handlers are IE-specific. Very useful little devils. I have used them on the latest variants of the v3, but I mention them here mainly to illustrate how much better they are, for this case, then onmouseover and onmouseout. The example (open it in IE) open small window in the top right corner and populates it each time any of these 4 handlers are called. Move your mouse around the menu and be ready to puke at the number of times onmouseover/out are called.

Mouse events

This nicely influence the speed, in all the good ways.

A degree of freedom

Credits for this goes to John Gallant of the PiE fame. In his flyout menu example, he implemented a fabulous little trick, shown on the following screenshot.

Mouse events

He placed each of the nested lists inside a div, which was slightly larger than the list itself, by adding padding to it. The whole div is then negatively margined for the same value used for padding. Since div is transparent, you don’t see this, but you notice that submenus does not disappear when your hand slips a bit off the submenu. Not 100% slip-proof, but very close.

My examples are so simple, that I don’t even need the extra element and use the nested ul elements for that, while all the styles are applied on the li elements.

Your turn

There you go. Checkout my simple examples, fly through the instructions and don’t forget to check the Troubleshooting section if you have problems.

And implement, implement, implement…