Hello. I'm Aleksandar Vacić, professional web developer and wine maker in the making.
Learn more about me or see what I can do for you.

My work & services

WCH 2

After the last post, I knew that only IE/Win had any benefit from this script. This way I was able to streamline the script and completely remove the dependency on other scripts. It’s not even needed to do anything on the page load. I also removed the support for IE 5.0 and concentrated on iFrame technique. And it’s a lot smaller: 4.65kB, heavily commented.

Script now has only three functions. WCH_Hider() does all the browser checks and creates the hiding iFrame. WCH_HideWndCtrl() is placing the hider below the layer that needs to go over windowed controls. WCH_ShowWndCtrl is removing the hider.

For those of you wondering what this is all about…read this entry that will explain the problem at hand. Now, on to version 2. I will still explain every part of the script, as I think that this version should be used in the future – it’s much smaller, faster, independent…simply better.

How to use it

This script is useful if you have dynamic layers that pop-out after page load, like menu scripts, fancy widgets and similar stuff. To prevent drop-downs to show through your layer, just call the function that will hide the portion of drop-down where layer is located.

if ( typeof(WCH_HideWndCtrl) != "undefined" )
	WCH_HideWndCtrl(this.submenu, this);

This type of calling allows you to freely work, regardless if WCH is actually loaded or not. When your layer is hidden, just call the opposite function in the same way:

if ( typeof(WCH_ShowWndCtrl) != "undefined" )
	WCH_ShowWndCtrl(this.submenu, this);
Creating Hider

WCH_Hider still takes the same two parameters: layer under which hider should be placed and the container for both of them. If the first parameter is not passed (i.e. nothing is passed), it simply exits. Then we check for browser compliance. Only IE5+/Win will pass this check:

var bBrowserOk = (document.all && document.getElementById);
if ( !bBrowserOk ) return null;

And only IE5.5+ will pass this check:

bBrowserOk = (bBrowserOk &&
typeof(document.body.contentEditable) != "undefined");
if ( !bBrowserOk ) return null;

Object detection at its best (for the first time in my dev life, MSDN was very useful). No user-agent spoofing can trick this.

After this line, I try to access the hiding iFrame element. If it’s there, jolly good, work done. If not, create it. First, we need a container, where hider iFrame will be inserted. That pointer is passed in the function call. If it’s not, assume it’s body.

if ( typeof(vContainer) == "undefined" )
	oContainer = document.getElementsByTagName("BODY")[0];
else if ( typeof(vContainer) == "string" )
	oContainer = document.getElementById(vContainer);
else
	oContainer = vContainer;

There is one nice IE/Win’s proprietary style rule that allows the execution of various visual filters. Here, Alpha filter is very useful, as it is rendering the frame invisible (this is not the same as CSSvisibility). Unfortunately, my test showed that applying the filter in IE5.5, even with SP2 installed, crashes the browser. Hence another object detection (compatMode property exists only in IE6+):

var sFilter = (typeof(document.compatMode) != "undefined")
? "filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);" : "";

Next, we need to get the value of z-index for our layer (remember, we need to place the hider one z-index step below the layer). First try with DOM, then with runtime style (value from stylesheet files). If we can’t get the value, or it’s less than two, do nothing since there is no room for the hider.

var zIndex = oLayer.style.zIndex;
if ( zIndex == "" )
	zIndex = oLayer.currentStyle.zIndex;
zIndex = parseInt(zIndex);

if ( isNaN(zIndex) ) return null;
if (zIndex < 2) return null;

March 17: I have changed the highlighted line above from if ( zIndex == "" && document.compatMode == "CSS1Compat" ) to shown one. Second condition effectively excluded IE5.5 (as zIndex was always 0 then and it got out on the last line), causing the script not to have effect in it.

Finally, create the hider element and get its pointer (line breaks added for clarity).

zIndex--;
oContainer.insertAdjacentHTML("afterBegin",
	'<iframe src="about:blank" id="hider' + oLayer.id + '"' +
	' scroll="no" frameborder="0"' +
	' style="position:absolute;visibility:hidden;' +
	sFilter +
	'border:0;top:0;left;0;width:0;height:0;' +
	'background-color:#ccc;z-index:' + zIndex + ';">' +
	'</iframe>'
);
oIframe = document.getElementById("hider" + oLayer.id);

Initially, hider is hidden. It first need to be given proper size and position.

Hide / show

Both hiding and revealing functions call the previous one. Work is done is valid object pointer is returned. In the function that hides everything below the layer, WCH_HideWndCtrl, we first get the layer size and apply it to the hider and then do the same for position, before we change its visibility.

oIframe.style.width = oLayer.offsetWidth + "px";
oIframe.style.height = oLayer.offsetHeight + "px";

oIframe.style.left = oLayer.offsetLeft + "px";
oIframe.style.top = oLayer.offsetTop + "px";

oIframe.style.visibility = "visible";

In the opposite function, we simply hide the hider, thus revealing everything below it.

Wait? Something missing…

Yup, there is no IE 5.0 support. This fancy iFrame hiding is not possible there. In the 1st gen of this script, I collected the pointers to windowed controls and then hide them with visibility:hidden. I didn’t like that too much, as it added 50% more code for 10% more users.

Should this be added? I’m still thinkin’ about it…

tags: WCH
Comments: 3

Posted 6 years, 6 months agopermanent link

trackback URL: http://aplus.rs/wchdev/wch-2/trackback/

Voices from the crowd, 3 so far

First, thanks for doing this. People like you, the guy doing IE7, SuzyUK working on crossbrowser layouts, Meyer, and simplebits… make it worth struggling for clean, semantic, compliant code in a field dominated by IE. It’s also nice to see you continuing to clean up and improve your scripts. ;)

Once again chiming in with more than you might want to hear. ;). You can add very basic IE 5.0 support a couple ways. The very simplest would be just adding some sort of hook, basically, that checks if IE5 and then checks for the existence of a specific function that the user can choose to implement and then calls it. Least clutter to the code, yet still lets people account for IE5, if they have to, without having to modify your script. Personally, I’ll have to add in some code specifically for Flash and NS6, so it’s moot for me, but I know I would appreciate it otherwise, as many of us still have to meet client requirements of IE5+

In the last version I commented on swapping in and out a body class that hides all descendants with a certain class and then having one css rule such as
body.currentlyHidden .hideOnMenu{visiblity:hidden;}. This would only require a couple of lines of code (the test for IE5, and then assigning the body class with a RegExp to not touch any other classes on it), but it does have at least one shortcoming — it can cause stupid IE to refetch background images, if they depend on selectors with body.class, as it has to refigure that .css and doesn’t cache .css background-image).

Since then I have considered what may be a cleaner possibility. It should be possible to somehow add and remove just a .hideOnMenu{visiblity:hidden;} rule to the stylesheets. Add the rule on mouseover and remove it on mouseout. Haven’t thought about it too much, yet or even loooked at testing it, but this might be the simplest way, and actually wouldn’t take much code, either.

by Tim Connor
1937 years, 2 months after the post

Of course, for either of the last two, you could just use a selector for all selects, but it’s nice to be able to pick which items to hide, and that would be a trivial bit of code to swap out, either way.

by Tim Connor
1937 years, 2 months after the post

Tim, those are interesting ideas. I will certainly try some of those, possibly even this weekend, unless my girlfriend has other plans for me. :)

Expect another post, as soon as I have something to show. And a very big thank you for including me in such respectable company.

by aleck
1937 years, 2 months after the post

Post your opinion


? You need to enter your email, but rest assured it will not be published.

? Enter the link and it will be published.
? This blog strives to behave properly, as per XHTML 1.0 Strict spec. You can use the following tags, but please use them wisely:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
? I have enabled comment moderation so if your comment does not shows up after you submit it, don't worry. I will review it and if it's nice and to the point, I'll approve it. This measure is up mostly to fight spam and trolls.

Tags or categories or topics...

Lots of ramblings on this blog...might be easier for you to find your juice through these tags:

Post a job. Find one. authenticjobs.com