A project that I am working on, teaches me some cool Javascript techniques every now and then. We needed to show a navigation area and the main content area. The obvious answer was to use frames. We also had to have something that can control both these frames. I decided on using iFrames since they would be flexible and serve the purpose of the project well.
There are two cool things that I want to write about today.
- Toggling the display of iFrames - turn on the navigation frame or turn it off
- Automatically resizing the frames when the browser size changes - user resizes, maximize window etc
The code will follow, but the major issues came up because of the differences between Firefox and IE. The window.onresize event fires when the window gets resized, and when you resize the iframe on that, you get another resize event. So this gets in a loop and can lead to a crash. Firefox emits the onresize event only once. The IE specific window.onresizeend event is sent only once - when the window is first opened - I did not get it even after resizing the window after the initial display.
The toggle seemed simple - make the visibility property of the iFrame style to either 'visible' or 'hidden' and I would have the toggle in place. That works, but only in Firefox! And then, what's the use of hiding the navigation bar if your main frame does not expand to utilize the space created! So you need to resize the frames too!
Apart from all that, I also found a handy debugging method! If I printed all the properties of an object, I would be able to figure out a lot more on what's happening and what's available on a particular browser. Checkout the printVars() function in the code. We do something similar to that very often in PHP and Flash ActionScript and doing that in JavaScript was much better than using alert's for debugging!
-
var resizeTimeout = undefined;
-
var resizeInProgress = false;
-
-
function resizeComplete()
-
{
-
clearTimeout(resizeTimeout);
-
resizeInProgress = false;
-
}
-
-
function resetHandler()
-
{
-
if (isBrowser("IE") && resizeInProgress == false)
-
{
-
if (resizeTimeout != undefined)
-
{
-
clearTimeout(resizeTimeout);
-
}
-
resizeTimeout = setTimeout("resetSize();", 500);
-
}
-
else if (isBrowser("FF"))
-
{
-
resetSize();
-
}
-
}
-
function resetSize(obj)
-
{
-
var w;
-
var h;
-
var deductW = 210;
-
var deductH = 110;
-
-
var myWidth = 0, myHeight = 0;
-
if( typeof( window.innerWidth ) == 'number' )
-
{
-
//Non-IE
-
myWidth = window.innerWidth;
-
myHeight = window.innerHeight;
-
}
-
else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
-
{
-
//IE 6+ in 'standards compliant mode'
-
myWidth = document.documentElement.clientWidth;
-
myHeight = document.documentElement.clientHeight;
-
}
-
else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
-
{
-
//IE 4 compatible
-
myWidth = document.body.clientWidth;
-
myHeight = document.body.clientHeight;
-
}
-
-
if (isBrowser("IE"))
-
{
-
clearTimeout(resizeTimeout);
-
resizeTimeout = setTimeout("resizeComplete();", 1500);
-
w = myWidth - deductW;
-
h = myHeight - deductH;
-
resizeInProgress = true;
-
//alert("w "+w+", h"+h);
-
try
-
{
-
navFrame.resizeTo(200,h);
-
mainFrame.resizeTo(w,h);
-
}
-
catch(e)
-
{
-
//alert(e.message);
-
}
-
}
-
else if (isBrowser("FF"))
-
{
-
var obj = MM_findObj("navFrame");
-
var obj2 = MM_findObj("mainFrame");
-
w = myWidth - deductW;
-
h = myHeight - deductH;
-
obj.setAttribute("height", h );
-
obj2.setAttribute("width", w );
-
obj2.setAttribute("height", h );
-
}
-
}
-
window.onresize = resetHandler;
-
-
function printVars(obj)
-
{
-
var str = "OBJECT: "+obj+"<br />";
-
for(var prop in obj)
-
{
-
str += "prop "+prop+" - "+obj[prop]+"<br />";
-
}
-
MM_findObj("debugMsg").innerHTML = str;
-
}
-
-
function isBrowser(which)
-
{
-
var toCheck;
-
switch (which)
-
{
-
case "IE" : toCheck = "MSIE";
-
break;
-
case "FF" : toCheck = "Firefox";
-
break;
-
}
-
if (undefined != toCheck)
-
{
-
return (navigator.userAgent.indexOf(toCheck) != -1)
-
}
-
return false;
-
}
-
-
var TOCVisible = true;
-
function toggleTOC()
-
{
-
var obj = MM_findObj("navFrame");
-
var obj2 = MM_findObj("mainFrame");
-
if (TOCVisible)
-
{
-
if (isBrowser("IE"))
-
{
-
navFrame.resizeTo(0,410);
-
mainFrame.resizeTo(760,410);
-
mainFrame.moveTo(9,60);
-
}
-
else if (isBrowser("FF"))
-
{
-
obj.setAttribute("width", 0);
-
obj.style.visibility = 'hidden';
-
obj2.setAttribute("width", 760 );
-
obj2.style.left = '0px';
-
}
-
TOCVisible = false;
-
}
-
else
-
{
-
if (isBrowser("IE"))
-
{
-
navFrame.resizeTo(200,410);
-
mainFrame.resizeTo(560,410);
-
mainFrame.moveTo(209,60);
-
}
-
else if (isBrowser("FF"))
-
{
-
obj.setAttribute("width", 200);
-
obj.style.visibility = 'visible';
-
obj2.setAttribute("width", 560 );
-
obj2.style.left = '209px';
-
}
-
TOCVisible = true;
-
}
-
//printVars(obj2.style);
-
}
-
-
function MM_findObj(n, d) { //v4.01
-
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
-
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
-
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d .forms.length;i++) x=d.forms[i][n];
-
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
-
if(!x && d.getElementById) x=d.getElementById(n); return x;
-
}
-
-
function init()
-
{
-
resetSize();
-
}
-
</script>
-
</d></script></head>
-
<body onLoad="init();">
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
-
</tr>
-
</table>
-
<!-- MAIN CONTENT AREA STARTS HERE -->
-
<table width="100%" border="0" cellpadding="0" cellspacing="1">
-
</tr>
-
</table>
-
<!-- MAIN CONTENT AREA ENDS HERE -->
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
-
</tr>
-
</table>
-
<div id="debugMsg"></div>
-
</body>
-
</html>
I am not putting in any code explanation here, hope you find the code easy to follow. You will need to create the nav.htm and main.htm files to test this.
Comments welcome!
0 comments ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment