Those things that refuse to obey

While developing AD xMenu, this script was incorporated to allow menu to pass over select boxes and similar windowed controls.

It worked so good, and was so easy to implement it for any layer, that I moved it to separate script and added few bits to ease-off integration with other scripts.

What’s it for?

Take a look at this example. Maroon layer is absolutely positioned and it goes over select box.

Did I say over?

In the old days, when there was nothing dynamic about HTML, browser makers used OS controls to draw HTML form elements. That means that they were at the “lower-level” compared to HTML browser engine and was thus untouchable for web authors. This was most obvious in revolutionary IE4. Microsoft changed this in IE5 (all form elements but drop-downs), further enhanced it in 5.5 (iframes were also moved to HTML engine); other newer browsers followed similar path.

If you are using Gecko-based or Opera 7 browser, then you don’t see a need for this script (as everything is displayed correctly for you). Same goes for Safari, as I hear. But you are a very small minority. Regular Windows users (those that we make websites for), use IE. And IE still uses OS control for one form element: select list (aka drop-down box).

So in IE, drop-down punch through the layer.

This script uses one fine trick to overcome this problem. (Danger ahead: in the following text, I will identify term browser with IE).

The old way…

This was usually the problem with layers that appeared when hovering some spot (since you can’t really control what is below the area where layer appears).

It became a nuisance and only available technique was to hide form elements when layer is shown. But if you have large number of form elements, then that takes a long time, sometimes up to 10s, which frustates the user (since it totally blocks IE).

Since IE 5, problem was greatly minimized - I have yet to see a web page which have this amount of drop-down boxes (that will be a usability nightmare by itself). So, all web developer needed to do is something like this:

    var aDD = new Array();
    aDD[aDD.length] = "document.forms['form name'] _
       .elements['drop-down name']";

(" _" was used to denote display break. In real code, connect these two lines.)

This will collect pointers to all select elements on the page. When layer is shown, do eval() for all this with style.visibility = "hidden".

This is how WCH is still doing, when it detects IE5 (functions WCH_HideWndCtrl4Oldies() and WCH_ShowWndCtrl4Oldies() in the script). In the WCH_Initialize() function, change this line to point to your array (aDD from above).

    if ( !WCH_bSupportHider && xDef(SG_aDDs) ) {
    	WCH_aDropDown = SG_aDDs;
The new way

In IE5.5, Microsoft has changed its code so that iFrame was drawn from HTML engine. And since it was a frame, it was drawn over any windowed control on the page. Unknown programer came up with idea to use this feature to resolve the problem at-hand, and contacted Joe King who wrote this explanation.

So, we need to dynamically insert the iFrame just below the layer in the z-index order and problem solved. IE’s insertAdjacentHTML function is used for that, emulated for other browsers using Thor Larholm’s code.

For this script to work, WCH_Initialize should be executed on window.onload. Then add this call to your show-layer function:

    WCH_HideWndCtrl(oLayer, oNewHiderContainer);

and this code for hide-layer function:

    WCH_ShowWndCtrl(oLayer, oNewHiderContainer);

oLayer is the layer object you are displaying. By default, iFrame is inserted as a child of the body element. This is fine, if you don’t use position:relative on the page when “phone-book” feature kicks-in. This means that if you have a layer with z-index of 100 inside of relatively positioned box, hider iFrame with z-index of 99 (WCH script will give him this, but it will be the same if it has value of 1) will be above the layer.

So, in such case, pass the object representing the position container as the second parameter.

And that is all. Have fun and report back any problems you encounter.