Resizing an Iframe Based on Content

Resizing an iframe based on content

We had this type of problem, but slightly in reverse to your situation - we were providing the iframed content to sites on other domains, so the same origin policy was also an issue. After many hours spent trawling google, we eventually found a (somewhat..) workable solution, which you may be able to adapt to your needs.

There is a way around the same origin policy, but it requires changes on both the iframed content and the framing page, so if you haven't the ability to request changes on both sides, this method won't be very useful to you, i'm afraid.

There's a browser quirk which allows us to skirt the same origin policy - javascript can communicate either with pages on its own domain, or with pages it has iframed, but never pages in which it is framed, e.g. if you have:

 www.foo.com/home.html, which iframes
|-> www.bar.net/framed.html, which iframes
|-> www.foo.com/helper.html

then home.html can communicate with framed.html (iframed) and helper.html (same domain).

 Communication options for each page:
+-------------------------+-----------+-------------+-------------+
| | home.html | framed.html | helper.html |
+-------------------------+-----------+-------------+-------------+
| www.foo.com/home.html | N/A | YES | YES |
| www.bar.net/framed.html | NO | N/A | YES |
| www.foo.com/helper.html | YES | YES | N/A |
+-------------------------+-----------+-------------+-------------+

framed.html can send messages to helper.html (iframed) but not home.html (child can't communicate cross-domain with parent).

The key here is that helper.html can receive messages from framed.html, and can also communicate with home.html.

So essentially, when framed.html loads, it works out its own height, tells helper.html, which passes the message on to home.html, which can then resize the iframe in which framed.html sits.

The simplest way we found to pass messages from framed.html to helper.html was through a URL argument. To do this, framed.html has an iframe with src='' specified. When its onload fires, it evaluates its own height, and sets the src of the iframe at this point to helper.html?height=N

There's an explanation here of how facebook handle it, which may be slightly clearer than mine above!



Code

In www.foo.com/home.html, the following javascript code is required (this can be loaded from a .js file on any domain, incidentally..):

<script>
// Resize iframe to full height
function resizeIframe(height)
{
// "+60" is a general rule of thumb to allow for differences in
// IE & and FF height reporting, can be adjusted as required..
document.getElementById('frame_name_here').height = parseInt(height)+60;
}
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>

In www.bar.net/framed.html:

<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>

<script type="text/javascript">
function iframeResizePipe()
{
// What's the page height?
var height = document.body.scrollHeight;

// Going to 'pipe' the data to the parent through the helpframe..
var pipe = document.getElementById('helpframe');

// Cachebuster a precaution here to stop browser caching interfering
pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();

}
</script>

Contents of www.foo.com/helper.html:

<html> 
<!--
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content
-->
<body onload="parentIframeResize()">
<script>
// Tell the parent iframe what height the iframe needs to be
function parentIframeResize()
{
var height = getParam('height');
// This works as our parent's parent is on our domain..
parent.parent.resizeIframe(height);
}

// Helper function, parse param from request string
function getParam( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
</script>
</body>
</html>

How to automatically resize iframe content size when browser window resize?

Your site is restricted from making changes to the content of an iframe. If you control the site inside the iframe, you can set up a message-system between the two sites. It might be worth checking if one exists even if you don't control the other site.

Otherwise, I would recommend simply refreshing the content of the iframe:

$( '#iframe' ).attr( 'src', function ( i, val ) { return val; });

As misorude mentioned in a comment you should contain this line so it doesn't fire immediately upon resize, since that would send an unreasonable amount of requests to the remote site.

Adjust width and height of iframe to fit with content in it

<script type="application/javascript">

function resizeIFrameToFitContent( iFrame ) {

iFrame.width = iFrame.contentWindow.document.body.scrollWidth;
iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
}

window.addEventListener('DOMContentLoaded', function(e) {

var iFrame = document.getElementById( 'iFrame1' );
resizeIFrameToFitContent( iFrame );

// or, to resize all iframes:
var iframes = document.querySelectorAll("iframe");
for( var i = 0; i < iframes.length; i++) {
resizeIFrameToFitContent( iframes[i] );
}
} );

</script>

<iframe src="usagelogs/default.aspx" id="iFrame1"></iframe>

Make iframe automatically adjust height according to the contents without using scrollbar?

Add this to your <head> section:

<script>
function resizeIframe(obj) {
obj.style.height = obj.contentWindow.document.documentElement.scrollHeight + 'px';
}
</script>

And change your iframe to this:

<iframe src="..." frameborder="0" scrolling="no" onload="resizeIframe(this)" />

As found on sitepoint discussion.

Resize iframe to content with Jquery

You just need to apply your code on the iframe load event, so the height is already known at that time, code follows:

$("#IframeId").load(function() {
$(this).height( $(this).contents().find("body").height() );
});

See working demo . This demo works on jsfiddle as I've set the iframe url to a url in the same domain as the jsfiddle result iframe, that is, the fiddle.jshell.net domain.

UPDATE:

@Youss:
It seems your page for a strange reason don't get the body height right, so try using the height of the main elements instead, like this:

$(document).ready(function() {
$("#IframeId").load(function() {
var h = $(this).contents().find("ul.jq-text").height();
h += $(this).contents().find("#form1").height();
$(this).height( h );
});
});


Related Topics



Leave a reply



Submit