Dynamically Resized IFrames - Part 2: Fitting the Content
Summary
This article describes how to eliminate multiple scroll bars
when using the IFrame tag, by dynamically resizing the IFrame
to fit the content in the frame.
This article is part 2 in a series on how to eliminate "scroll
bar hell" when using Iframes. Part 1 "Dynamically
Resized IFrames - Part 1: Eliminating Multiple Scroll Bars"
describes how to make the IFrame shrink or grow to fill the
browser window, so you only get the "inner" IFrame
scroll bar, eliminating the outer browser window scroll bar.
Background
See Part 1 of
this series for the background information on how IFrames
are useful but can lead to excessively complicated multiple
scrolling regions on the user's screens.
Browser Compatibility
This solution has been tested in Internet Explorer 6.0.
Please send us feedback
if you find it works (or does not work) in other browser brands
and versions.
The Solution
Note - this solution will only work:
- if you have control over the content of BOTH pages (the
"outer" page with the IFRAME tag, and the "inner
" page being displayed in the IFRAME)
- if the outer and inner pages are being hosted on the same
domain (and it's a little less work if they are on the same
server)
The solution has two basic steps:
- measure the height of the IFrame's content once the content
has loaded
- set the height of the IFrame to the height of the content
First, let's assume this is your IFrame tag:
<IFRAME
src="http://myhost.mydomain.com/innerpage.html">
1. Set width = 100% and add an ID attribute to your IFrame
You should set WIDTH=100% - this normally has the desired
effect.
Your IFrame must have an ID attribute that is unique across
all HTML elements on the page. This makes the scripting easier
later, and allows for having multiple IFrames on the page
that all resize themselves.
Here is your modified IFrame:
<IFRAME ID="myiframe"
src="http://myhost.mydomain.com/innerpage.html"
width=100%>
2. Create a function to measure the height of the content,
and set the IFrame height
To measure the height of the content, use the document.frames[]
collection to access the IFrame's "inner"
document.
If you use the document.all collection (or
the IFrame ID object directly), you will be able to manipulate
the IFrame tag itself - like set the height - but not access
the inner content.
The JavaScript to get the height of the content is:
document.frames['myiframe'].document.body.scrollHeight;
The JavaScript to set the height of the IFrame is:
myiframe.height = <desired height>;
So the resulting JavaScript function to resize the IFrame
looks like this:
<SCRIPT LANGUAGE="JavaScript">
function resizeIframeToFitContent(iframe) {
// This function resizes an IFrame object
// to fit its content.
// The IFrame tag must have a unique ID attribute.
iframe.height = document.frames[iframe.id]
.document.body.scrollHeight; }
</SCRIPT>
3. Set your initial IFrame height to 0
If the IFrame is bigger than its content, the scrollHeight
attribute will return the height of the IFrame, not the "minimum"
it needs for the content. So to make sure you are getting
only the minimum height you need to show your content, set
the IFRAME tag to HEIGHT=0 in your HTML.
<IFRAME ID="myiframe"
src="http://myhost.mydomain.com/innerpage.html"
width=100%
height=0>
Like all HTML elements and attributes, this will only take
effect when the page is initially loaded; scripts that modify
this attribute later will permanently modify what it looks
like on-screen; although a "View - Source" command
will still show the original value.
4. Call the resize function when the content is loaded
IE has an "onload" event for the IFrame tag that
we can use to call our resize function when the inner page
has loaded (and the content height is known).
Add the onload event handler to your IFRAME tag:
<IFRAME ID="myiframe"
src="http://myhost.mydomain.com/innerpage.html"
width=100%
height=0
onload="resizeIframeToFitContent(this)">
The "this" object refers to the HTML element that
holds the event handler, in this case it is a handle to the
<IFRAME> tag itself.
Done! (maybe...)
Now test your page. You may find that the solution works
now, and you need to go no further. But if you get a javascript
error "Access Denied" (you may have to double-click
a little yellow warning triangle in the bottom left corner
of the IE window to see it) then you need to do the next step:
5. Browser Security Note
If your "inner" and "outer" pages are
on different servers, both pages need to be modified to allow
the browser scripts to execute.
Add this JavaScript to the top of BOTH pages:
<SCRIPT LANGUAGE="JavaScript">
document.domain = "mydomain.com";
</SCRIPT>
Replace "mydomain.com" with your actual domain
name.
- Both documents MUST be set to the same domain, or the
security error will happen.
- The domain you choose MUST be the same as the URL being
used to access the page.
- You must access the outer and inner pages with a fully
qualified host name e.g. http://myhost.mydomain.com/...,
not just http://myhost/...
This will tell the browser that both pages are coming from
the same domain (which implies they are controlled by the
same company and can be trusted) and hence scripts on one
page can access the content (i.e. body.scrollHeight) of the
other page.
Notes
This solution will not adjust the IFrame height if the page
is resized; the IFrame height is only determined when the
content is initially loaded. It also will not resize when
only the IFrame content changes (e.g. by clicking a link in
the inner page that reloads only the inner page).
I tried unsucessfully to get the onresize and onresizeend
events to call my resize function; if anyone has success with
this please send us feedback and we will post your solution
(and give you credit).
Related Information (mostly MSDN)
|