Iframe Resizer

Nov2008Nov 20, 08

There, I said it. I actually found a use for the legendary iframe. Truthfully, it was for a colleague, but it seemed like the best method for the purpose of the poll widget he was creating. A simple poll inside an iframe, but the results display is considerably larger than the initial form display.

Given that the problem was JavaScript related, I couldn't help but suggest a solution. Normally, I would have just used AJAX so the DOM would be accessible, but I still enjoy a good 5 line challenge. Around 8 out of 10 of you will have flames in your eyes at this point - stay cool. The other two statistical friends have the jQuery logo burning in their eyes. Well, I'm not one to use external libraries for just one of their methods, so that's not going to show up in this tutorial. Let's get started, this won't hurt a bit.

As a step by step, unobtrusive JavaScript always begins in a similar way - add your function to window.onload using your favorite method. For this example, I'm going to use the simple way:

window.resize_onload_old = window.onload ? window.onload : function(){};
window.onload = function() {
	// our code will go here!
	window.resize_onload_old();
};

Add a wrapping div to the body of the framed document. This is needed in order to get Internet Explorer working (the <body> has incorrect offsetHeight). Give this new div an id of resize_wrap.

...
<body>
	<div id="resize_wrap">
		<!-- Everything should be placed inside this div -->
	</div>
</body>
...

Although not an actual step, you should be aware that the script works best when the contained document has no margins or padding. Here is a quick way to do that.

Code:
<style type="text/css">html,body{margin:0;padding:0;}</style>

Now the script itself. Our first line simple grabs a reference to the iframe to be resized:

window.frame = window.top.document.getElementById("resize_me");

Then we need to calculate the "distance" (difference in height) that between the iframe's height and the height of our framed document. Adding 1 to this distance gets it working in IE 6, though it will add 1 pixel to the height in all modern browsers. I'm fine with that, so it's a simple calculation:

Code:
var dist = document.getElementById("resize_wrap").offsetHeight - window.frame.offsetHeight + 1;

Finally, we'll create a series of Timeouts that will smoothly re-size the iframe. In order to make it truly smooth, I have chosen to emulate a acceleration sinusoidally:

for(var h=1; h<=dist; h+=dist/100)
	window.setTimeout("window.frame.style.height = '"+(window.frame.offsetHeight + (Math.sin(h/dist*Math.PI - Math.PI/2)+1)/2*dist)+"px';",h*5);

...And that's it! Here is the completed JavaScript block for your reference:

window.resize_onload_old = window.onload ? window.onload : function(){};
window.onload = function() {
	window.frame = window.top.document.getElementById("resize_me");
	var dist = document.getElementById("resize_wrap").offsetHeight - window.frame.offsetHeight + 1;
	for(var h=1; h<=dist; h+=dist/100)
		window.setTimeout("window.frame.style.height = '"+(window.frame.offsetHeight + (Math.sin(h/dist*Math.PI - Math.PI/2)+1)/2*dist)+"px';",h*5);
	window.resize_onload_old();
};

*note: If you want to remove the scroll bar while resizing, add this to the iframe's CSS:
html,body{overflow:hidden;}

About Jason Miller:

I am a JavaScript developer from Waterloo, Ontario, Canada. When I am not typing green code onto a black screen, you might find me at the nearest coffee pub checking out the brew. I run a internet firm called developIT and maintain blogs and web apps when I can.
Comments
YSLim#
cool! thanks for sharing!
Leave a Comment

Post Comment