cross-domain iframe resize

The thing is - there is no other way than using Cross-Domain Messaging for this since you need to get the computed height from a document in one domain, to a document in a different domain.

So, either you do this using postMessage (works in all moder browsers), or you spend 5 minutes adapting the resize iframe example from easyXDM.

The other party really just needs to copy a few files onto their domain, and add a single line of code to their document..


Similar to what Sean has mentioned, you can use postMessage. I've spent so much time trying different ways to resize iframe with cross-domain but no luck until I stumbled on this great blog post by David Walsh: http://davidwalsh.name/window-iframe

This is a combination of my code and David's solution. My solution is geared specifically toward resizing iframes.

In the child page, find the height of the page and pass it to the parent page (which contains the iframe). Replace element_id with your element id (html, body, whatever).

<script>
function adjust_iframe_height(){
    var actual_height = document.getElementById('element_id).scrollHeight;
    parent.postMessage(actual_height,"*"); 
    //* allows this to post to any parent iframe regardless of domain
}
</script>

<body onload="adjust_iframe_height();"> 
//call the function above after the content of the child loads

On the parent window, add this code. Replace iframe_id with your iframe ID:

<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child window
eventer(messageEvent,function(e) {
  console.log('parent received message!:  ',e.data);
  document.getElementById('iframe_id').height = e.data + 'px';
},false);
</script>

If you open the console, you will see the height being printed in the console log. This will help you in debugging which is why I left it there.

Best, Baker


Having looked a lots of different solution to this I ended up writing a simple small library to take a account of a number of different use cases. As I needed a solution that supported multiple user generated iFrames on a portal page, supported browser resizes and could cope with the host page JavaScript loading after the iFrame. I also add support for sizing to width and a callback function and allow the override of the body.margin, as you will likely want to have this set to zero.

https://github.com/davidjbradshaw/iframe-resizer

The iframe code is just a little self-contained JavaScript, so that it's a good guest on other people pages.

The script is then initialised on the host page with the following available options.

iFrameResize({
    log                    : true,  // For development
    autoResize             : true,  // Trigering resize on events in iFrame
    contentWindowBodyMargin: 8,     // Set the default browser body margin style (in px)
    doHeight               : true,  // Calculates dynamic height
    doWidth                : false, // Calculates dynamic width
    enablePublicMethods    : true,  // Enable methods within iframe hosted page 
    interval               : 32,    // interval in ms to recalculate body height, 0 to disable refreshing
    scrolling              : false, // Enable the scrollbars in the iFrame
    callback               : function(messageData){ // Callback fn when message is received
        $('p#callback').html(
            '<b>Frame ID:</b> '    + messageData.iframe.id +
            ' <b>Height:</b> '     + messageData.height +
            ' <b>Width:</b> '      + messageData.width + 
            ' <b>Event type:</b> ' + messageData.type
        );
    }
});