Reputation: 2387
I'm looking for a good cross-domain iframe resizing script that adjusts its height based on its content. I have access to the html/css for the source of the iframe as well. Is there any out there?
Upvotes: 29
Views: 37041
Reputation: 9659
If your users are on modern browsers, you can solve this quite easily with postMessage in HTML5. Here's a quick solution which works well:
The iframe page:
<!DOCTYPE html>
<head>
</head>
<body onload="parent.postMessage(document.body.scrollHeight, 'http://target.domain.com');">
<h3>Got post?</h3>
<p>Lots of stuff here which will be inside the iframe.</p>
</body>
</html>
The parent page which contains the iframe (and would like to know its height):
<script type="text/javascript">
function resizeCrossDomainIframe(id, other_domain) {
var iframe = document.getElementById(id);
window.addEventListener('message', function(event) {
if (event.origin !== other_domain) return; // only accept messages from the specified domain
if (isNaN(event.data)) return; // only accept something which can be parsed as a number
var height = parseInt(event.data) + 32; // add some extra height to avoid scrollbar
iframe.height = height + "px";
}, false);
}
</script>
<iframe src='http://example.com/page_containing_iframe.html' id="my_iframe" onload="resizeCrossDomainIframe('my_iframe', 'http://example.com');">
</iframe>
Upvotes: 37
Reputation: 13097
Having failed to find a solution that dealt with all the different use-cases for this I ended up writing a simple js lib that supports both width and height, resizing content and multiple iframes on one page.
https://github.com/davidjbradshaw/iframe-resizer
Upvotes: 15
Reputation: 11
I have a whole different solution to cross domain iframe resizing. It involves procuring a copy of the target page that you will put in your iframe, writing it locally, then putting that copy into your iframe and resizing based on same domain access to the dom inside the frame.
an example follows:
<?php
if(isset($_GET['html'])) $blogpagehtml = file_get_contents(urldecode($_GET['html']));
else $blogpagehtml = file_get_contents('http://r****d.wordpress.com/');
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($blogpagehtml);
libxml_use_internal_errors(false);
$anchors = $doc->getElementsByTagName("a");
foreach($anchors as $anchor) {
$anchorlink=$anchor->getAttribute("href");
if(strpos($anchorlink,"http://r****d.wordpress")===false) $anchor->setAttribute("target","_top");
else $anchor->setAttribute("href","formatimportedblog.php?html=".urlencode($anchorlink));
}
$newblogpagehtml = $doc->saveHTML();
$token = rand(0,50);
file_put_contents('tempblog'.$token.'.html',$newblogpagehtml);
?>
<iframe id='iframe1' style='width:970px;margin:0 auto;' src='tempblog<?php echo $token; ?>.html' frameborder="0" scrolling="no" onLoad="autoResize('iframe1');" height="5600"></iframe>
Upvotes: 0
Reputation: 101
The first script on this page - the one using postMessage in HTML5 - also works for iframes on mobile - by resizing the iframe to the content - for example syndicating cross-domain - you can easily scroll in iphones or android, in a way that's not possible with iframes otherwise
Upvotes: 1
Reputation:
Following code worked for me:
var iframe = document.getElementById(id);
iframe.height = iframe.contentDocument.body.scrollHeight;
Tested on Opera 11, IE 8 9, FF 8, Chrome 16
Upvotes: -2
Reputation: 4726
After some research, I ended up using html5's message passing mechanism wrapped in a jQuery pluging that makes it compatible with older browsers using various methods (some of them described in this thread).
The end solution is very simple.
On the host (parent) page:
// executes when a message is received from the iframe, to adjust
// the iframe's height
$.receiveMessage(
function( event ){
$( 'my_iframe' ).css({
height: event.data
});
});
// Please note this function could also verify event.origin and other security-related checks.
On the iframe page:
$(function(){
// Sends a message to the parent window to tell it the height of the
// iframe's body
var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
$.postMessage(
$('body').outerHeight( true ) + 'px',
'*',
target
);
});
I've tested this on Chrome 13+, Firefox 3.6+, IE7, 8 and 9 on XP and W7, safari on OSX and W7. ;)
Upvotes: 0
Reputation: 38046
EasyXDM can do just this :) This blog post explains the gist of it
Upvotes: 1