0

This has been asked many time, but I ask because no solution has worked for me and I have not found many of the right kinds of solutions. I want a static width, but a dynamic height based the inner content.

I'm hosting a blog on a subdomain, and am inserting it via iframe into a page on my main domain. I could set a static height and scroll so that users could still use the blog, but I want something that looks better. When I make new posts, or the user clicks on the comment section, I want the iframe to be able to automatically adjust in size, so that it can display all content without a scroll bar.

So far, I haven't found solutions that work, mainly because many involve pages that are on the same domain.

mateikav
  • 93
  • 3
  • 9

2 Answers2

2

Since you have control over the content in the iframe you could try window message events.

Add this to your frame content:

// post a message to the top window with information about the height
window.onload = function(){
    top.postMessage(document.body.scrollHeight, '*');
}

And this to your page containing the iframe:

// listen for the message and set the iframe height when it arrives
window.addEventListener( "message", function(event){
    document.getElementById('test').style.height = event.data+'px';
}, false);

<iframe id="test" src="test.html"/>

In response to your comment. Here are some ways you can update the iframe height when the iframe content changes.

1. Mutation Events

// listen to all descendants of the body and if there are any modifications, post an update to the top window 
document.body.addEventListener("DOMSubtreeModified", function(){
    top.postMessage(document.body.scrollHeight, '*');
}, false);

That approach has been depreciated. This is the replacement but it is not yet fully supported:

2. Mutation Observers

// create a MutationObserver to listen for modification to the body and post an update to the top window
var observer = new MutationObserver(function(){
    top.postMessage(document.body.scrollHeight, '*');
});
observer.observe(document.body, {childList: true, subtree: true});

I would go with the first option until the second is better supported

louisbros
  • 865
  • 5
  • 10
  • This works to set the iframe initially, but there is one issue. Let's say the user loads up the page, sees all the posts and clicks on one. What happens is if the post is longer than the original iframe height, the iframe will not automatically resize to accomodate for the new length. I don't know enough to fix this... – mateikav Apr 15 '13 at 05:32
  • I've added some options that should help you. – louisbros Apr 15 '13 at 10:31
  • This time, instead of expanding the actual height of the iframe, it adds a scroll bar and keeps the iframe height static to what it was set upon first load of the page. Of course, I might be putting this new code in the wrong place. I tried both the iframe content page and the page containing the iframe – mateikav Apr 15 '13 at 13:11
  • Okay, got it fixed. I was testing the new code addition on my WAMP test server, but as soon as I uploaded it to the domain it worked as it was supposed to. Thanks for all the help. – mateikav Apr 15 '13 at 16:16
0

Just thought I'd add that offsetHeight is more reliable than scrollHeight for working out the size of an iFrame. So long as the body margin is set to 0. The issue is ScrollHeight will only grow the size of the page, not reduce it. The margin issue can be overcome but it's a lot of code if you care about IE8.

MutationEvents are dead, use MutationObserver. Although it doesn't work in IE10 and below so you have to fall back to setInterval, which you should use with a timer of 32 if you don't want the user to see any screen flicker. RequestAnimationFrame is also useful to help with cutting out screen flicker.

You might be interested to look at https://github.com/davidjbradshaw/iframe-resizer which deals with all these issues.

Community
  • 1
  • 1
David Bradshaw
  • 11,859
  • 3
  • 41
  • 70