Advanced customising

There's a great deal you can do to get more interesting, colourful, useful, or bizarre functionality out of the customisation code. For example by using image links, defining link conditions and behaviours or opening customised windows. The script includes a javascript style sheet which is (relatively) easy to customise with conditional style definitions, and this is also where you can add any global onload functions you want to call. There's also a section on improving efficiency in older browsers, and information about adding filters and transition effects

On other pages are an accessibility guide, and tutorials about making an image-based navbar, using free alignment and relative positioning


Using image links

When reading this section, please bear in mind that there are some issues with the techniques described here. Read this section for interest, and relax in the knowledge that there is a much better way to incorporate images into your navbar.

So, adding a spot image such as the flower icon top left, can be done like this:

However if you want your images to be drawn from the same central folder, you will need to add baseHREF into the image path, like this:

Alternatively you can define the img srcs using absolute or base-relative paths, like the links. If you add images, you might need to increase the vertical padding to prevent them from hanging over the bottom. Note also that in the mozilla 5 browsers, images included in this way may be cropped to the top of the text layers.

Fiddly issues arise if you want to use an icon and some text in the same link name. Each browser has its own ideas about the relative alignment of text and images, so you'll need to use a combination of layers and CSS to get consistent results:

It works, but you should note that i've had to put the text in a separate layer for ns4, which nullifies the link. Also the code which creates a default-cursor layer for null URLs won't apply in this case, because it only looks for undefined values.

Also note that there's a bug in ie5.5 and ie6, where the browser continually reloads hidden images, whenever they're made visible, even if they exist in cache. This is why I removed the use of a spacing gif from Version 2.1 onwards (thanks to John Miller at Dynamic Drive who told me about the problem), and i've since found out that it also occurs with dynamically modified background images. If your site is very popular, you may end up consuming a large amount of bandwidth, perhaps even overloading your server in extreme cases, "like a mini D.O.S attack".

But image-based navbars do look very nice. So if this is what you want there's another way to do it, which avoids all these problems: The idea is to build a completely transparent top nav, which is superimposed on top of a normal html layout or image map. This will work much better and be truly cross-compatible - since the under-nav is html, it will still be navigable to people who use unsupported browsers or have javascript disabled. Check out this tutorial for more information.


Link conditions and behaviours

Using the variables from the sniffer script with your customisation code you can make parts of it browser specific - allowing you to discriminate about which browsers can see which parts of your site. For example, some of the links in this demo are win/ie5+ specific, which is done by conditionalising the link definition, eg:

Another idea is to randomise links, or use conditions like the referring url, the user's operating system, the local time or the date, eg:

Single quotes in link names do not need to be escaped, but further double quotes, or single or double quotes inside those will need escaping.

You could pre-define variables to build groups of links more efficiently, or add in information from a database, or a cookie, or the result of another process. Here's a trivial example:

Adding small functions before link definitions is an easy way of making behavioural adjustments, and you can trigger them by surrounding your link name with a function-call, eg:

This works in most browsers, but not always in Netscape 4 - it depends on what kind of functionality you want. Since the example above doesn't work in ns4 anyway (because dynamic font-styles are not natively supported) using functions is safer - it will degrade far better than inline-dhtml.

For window-level operations like window.print(), or where you need something truly robust, you can use a javascript: url, eg:

If you do use function calls as urls, you must use the javascript: pseudo-protocol, or they won't work at all.


Opening customised windows

This is also the approach to take if you want your links to open windows with defined properties. A window-opening function is built in from version 3.1.2 onwards, which includes parameters for the width and height of the window:

You can change the other properties - such as toolbars and scrolling - by editing the function, which is at the end of sniffer.js:

In fact this function is not just available to the menu, you can use it anywhere on pages which contain the dropdown menu script, like this


Conditional style definitions

style.js is a script-written style sheet, and there's space marked out in it if you wish to add new definitions for use in your customisation code, or for other stuff on your page. Using this you can go beyond scripting properties alone, and build a conditional style sheet which is accessible to normal HTML tags via the class attribute. The syntax of these definitions is the same as for normal CSS, except that all the special characters will need to be escaped - the characters that CSS uses a lot, such as curly-braces, semi-colons and brackets. eg:

Here we've defined a class called roman which is times new roman on a white background, blue text for everything except Netscape 4 where it's green, like this.

The font size for windows/ns4 and mac/opera 5 is set 1px larger, to compensate for an idiosyncrasy where text in the page body is one unit smaller than the same font size in other browsers. This can be particularly irritating if you use resizeable text, by defining font-sizes with a relative value such as "x-small" rather than an absolute unit like px or pt. The difference between x-small and xx-small is much greater than the difference between 12px and 11px.

But no worries - you can use conditional definitions to overcome this problem:


The reference stySTR is a string-compiling variable which is written at the very end - so creating new definitions means adding to this string, not defining it from nothing, hence the use of +=


Global onload functions

I had quite a few emails saying that the menu stops other scripts from working. On investigation it turned out that the script's use of window.onload nullifies the <body onload event - so any other code which relies on that event won't be triggered.

To compensate for this I built a generic onload function, which you can use to call others. There's space marked out at the bottom of style.js to define the function calls you want, eg:

Then paste this script anywhere in your page's source code:

Now refresh the page, and there it is. However please note - if you do this, the script will be expecting that function to appear on every page that has the dropdown menu; without it you will get the error "object expected". This makes it ideal for global scripting, but unsuitable for ad-hoc scripts - those which only appear on one or some of your pages - but there are some workarounds if this is what you need:

Also note that if you use static positioning, the browser's performance will be slowed once the positioning timeout begins. To try to avoid putting too much strain on the browser, any global onload functions will be called after the menu has completely loaded and rendered but before the static positioning loop kicks in.


Improving efficiency

In opera and netscape 4, the menus have to be built in advance, so the more images, menus and child menus you use, the longer it will take to compile and render them all. If you have a very complex layout, that's when a noticeable drag can appear. The best solution is to keep your nav simple and not have too many branches. But there are some specific things you can do to improve performance:


Filters and transition effects

It's possible to add special effects to individual menus. Functional in Internet Explorer 5.5 and 6 for Windows, effects are defined using the submenu properties and childmenu properties, so that a different filter or transition can be applied to each menu. The following guide introduces some of the possibilities, but a full list can be found at the msdn library visual filters and transitions reference

Static filters

A variety of interesting effects can be applied using static filters. For example, this will create menu translucency:

An equally nice effect is a gradiated shadow, as used in the msdn demo. This is achieved using the menu's built-in dropshadow as an enclosing border, and the addition of this Shadow filter:

If you plan to incorporate the same filter on every menu, you might find it easier to define a global variable:

Most filters only create a visible effect on the non-transparent portions of an element. This is important, because the menu itself is contained within another div, positioned inside it with margins on all sides; filters are applied to the whole div, so visual effects which also affect the transparent parts of an element will look weird. The MaskFilter is a good example:

In this case, the menu becomes transparent and its previously-invisible margins become magenta. Unless you specifically want strange results, it's best to avoid such filters. However you may want to experiment, in which case you might like to know that as a coincidental side-effect, it's possible to apply any css properties with this array value.

There is another side-effect to how filters are applied, which is seen if you use one which creates a physical offset or distortion when applied, such as Shadow to a small extent and Matrix transform most significantly:

You will find that not only does the menu distort, but the container does as well. Part of the container's purpose is to prevent the menus closing prematurely when offset to the extent that there's a gap between the nav and the menu, like the one at the top. If it's distorted, gaps will appear where mouse movement closes the menu. There are two solutions in this situation: either a) ensure that menus are not offset enough to create gaps; or b) apply a slow close timer to compensate.

Transitions

Transition effects are applied when the menu is opened, creating a transition with its visibility. There are quite a few to choose from, some of which are graceful and some intensely annoying, depending on how they're configured. The playschool demo is excessive, but gives an idea of the range of possibilities.

A particular favourite of mine is the wheel transition used in the Entertainment > Physical Jigsaw child menu at the top, like this:

Both Fade and Random dissolve look nice, and are reasonably subtle:

Or you might like pixellation, for that Mission Impossible vibe:

Bear in mind that effects like this, while very nice at first, can become irritating if used excessively. I suggest restraint; less is more.

Using a transition effect on a submenu which has a key trigger is not recommended - the transition will be played with every key press, instead of once per-opening, and i've yet to find a way round this; the child menus are not affected, only the submenus.