Resize Cross Domain Iframe Height

125,320

Solution 1

It is only possible to do this cross domain if you have access to implement JS on both domains. If you have that, then here is a little library that solves all the problems with sizing iFrames to their contained content.

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

It deals with the cross domain issue by using the post-message API, and also detects changes to the content of the iFrame in a few different ways.

Works in all modern browsers and IE8 upwards.

Solution 2

Minimum crossdomain set I've used for embedding fitted single iframe on a page.

On embedding page (containing iframe):

<iframe frameborder="0" id="sizetracker" src="http://www.hurtta.com/Services/SizeTracker/DE" width="100%"></iframe>
<script type="text/javascript">
  // Create browser compatible event handler.
  var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
  var eventer = window[eventMethod];
  var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
  // Listen for a message from the iframe.
  eventer(messageEvent, function(e) {
    if (isNaN(e.data)) return;

    // replace #sizetracker with what ever what ever iframe id you need
    document.getElementById('sizetracker').style.height = e.data + 'px';

  }, false);
</script>

On embedded page (iframe):

<script type="text/javascript">
function sendHeight()
{
    if(parent.postMessage)
    {
        // replace #wrapper with element that contains 
        // actual page content
        var height= document.getElementById('wrapper').offsetHeight;
        parent.postMessage(height, '*');
    }
}

// Create browser compatible event handler.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen for a message from the iframe.
eventer(messageEvent, function(e) {

    if (isNaN(e.data)) return;

    sendHeight();

}, 
false);
</script>

Solution 3

You need to have access as well on the site that you will be iframing. i found the best solution here: https://gist.github.com/MateuszFlisikowski/91ff99551dcd90971377

yourotherdomain.html

<script type='text/javascript' src="js/jquery.min.js"></script>
<script type='text/javascript'>
  // Size the parent iFrame
  function iframeResize() {
    var height = $('body').outerHeight(); // IMPORTANT: If body's height is set to 100% with CSS this will not work.
    parent.postMessage("resize::"+height,"*");
  }

  $(document).ready(function() {
    // Resize iframe
    setInterval(iframeResize, 1000);
  });
</script>

your website with iframe

<iframe src='example.html' id='edh-iframe'></iframe>
<script type='text/javascript'>
  // Listen for messages sent from the iFrame
  var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
  var eventer = window[eventMethod];
  var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

  eventer(messageEvent,function(e) {
    // If the message is a resize frame request
    if (e.data.indexOf('resize::') != -1) {
      var height = e.data.replace('resize::', '');
      document.getElementById('edh-iframe').style.height = height+'px';
    }
  } ,false);
</script>

Solution 4

If you have access to manipulate the code of the site you are loading, the following should provide a comprehensive method to updating the height of the iframe container anytime the height of the framed content changes.

Add the following code to the pages you are loading (perhaps in a header). This code sends a message containing the height of the HTML container any time the DOM is updated (if you're lazy loading) or the window is resized (when the user modifies the browser).

window.addEventListener("load", function(){
    if(window.self === window.top) return; // if w.self === w.top, we are not in an iframe 
    send_height_to_parent_function = function(){
        var height = document.getElementsByTagName("html")[0].clientHeight;
        //console.log("Sending height as " + height + "px");
        parent.postMessage({"height" : height }, "*");
    }
    // send message to parent about height updates
    send_height_to_parent_function(); //whenever the page is loaded
    window.addEventListener("resize", send_height_to_parent_function); // whenever the page is resized
    var observer = new MutationObserver(send_height_to_parent_function);           // whenever DOM changes PT1
    var config = { attributes: true, childList: true, characterData: true, subtree:true}; // PT2
    observer.observe(window.document, config);                                            // PT3 
});

Add the following code to the page that the iframe is stored on. This will update the height of the iframe, given that the message came from the page that that iframe loads.

<script>
window.addEventListener("message", function(e){
    var this_frame = document.getElementById("healthy_behavior_iframe");
    if (this_frame.contentWindow === e.source) {
        this_frame.height = e.data.height + "px";
        this_frame.style.height = e.data.height + "px";
    }
})
</script>

Solution 5

There is no options in javascript to find the height of a cross domain iframe height but you can done something like this with the help of some server side programming. I used PHP for this example

<code>
    <?php
$output = file_get_contents('http://yourdomain.com');
?>
<div id='iframediv'>
    <?php echo $output; ?>
</div>

<iframe style='display:none' id='iframe' src="http://yourdomain.com" width="100%" marginwidth="0" height="100%" marginheight="0" align="top" scrolling="auto" frameborder="0" hspace="0" vspace="0"> </iframe>

<script>
if(window.attachEvent) {
    window.attachEvent('onload', iframeResizer);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            iframeResizer(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = iframeResizer;
    }
}
   function iframeResizer(){
        var result = document.getElementById("iframediv").offsetHeight;

        document.getElementById("iframe").style.height = result;
        document.getElementById("iframediv").style.display = 'none';
        document.getElementById("iframe").style.display = 'inline';
    }
</script>
</code>
Share:
125,320
user874185
Author by

user874185

Updated on July 09, 2022

Comments

  • user874185
    user874185 almost 2 years

    I'm trying to change the iframe height parameter to the same px of the page being loaded within the iframe. The page that's being loaded in the iframe is coming from another domain.

    Different pages will be loaded up inside of the iframe causing the height of the iframe content to change, So I will need to grab the iframe content height and apply it to the iframe height parameter.

    Here a example of what im talking about: http://jsfiddle.net/R7Yz9/3/

    <div class="site"><a href="http://amazon.com/" target="_top">Amazon </a></div>
    <div class="site"><a href="http://cnn.com/" target="_top">Cnn </a></div>
    <div class="site"><a href="http://wikipedia.org/" target="_top">Wikipedia </a></div>
    <iframe id="source" src="http://amazon.com/" frameborder="0" scrolling="no" width="100%" height="100%"></iframe>
    

    .

    $(document).ready(function() {
        var iframe = $( "#source" );
        $( "a[target=_top]" ).click( function(){
            iframe.attr( "src", this.href );
            return false;
        }); 
    });
    
  • David Bradshaw
    David Bradshaw over 9 years
    @budamivardi It does work cross domain, you just need to put the second script on the remote domain.
  • o_O
    o_O about 9 years
    I think that's a tad deceptive. Most people (including the OP) are asking about sites they have no ability to put scripts in their code like Amazon, CNN, etc in the question. Yes, this plugin might work if you have access to all code but stating it's cross-domain is being intentionally sneaky.
  • Dimitar Spasovski
    Dimitar Spasovski almost 4 years
    I downvoted because this solution is not a full "cross domain" solution. Please add additional info that states that it works for "cross domain" cases only if you have access to both domains, which as @o_O stated is the case most of us are trying to solve.
  • David Bradshaw
    David Bradshaw almost 4 years
    @DimitarSpasovski their is no solution within the browser, if you are trying to do this with a site not under your control. Your only option is to ask the other site to host this JS for you.
  • stackers
    stackers almost 3 years
    finally, an answer that works! this is like the fifth one I've tried.
  • Neil Monroe
    Neil Monroe almost 3 years
    This will not work for pages in the iframe you cannot access the code for. It is a good solution if you control both the parent page and the embedded page, however.
  • luenib
    luenib about 2 years
    If you are using React, don't forget to use <script class="reactScript">
  • JoeGalind
    JoeGalind almost 2 years
    This worked for me. I did a little tweak... moving the iframeResize() function to the resize event, instead of emmiting it every second. $( window ).resize(function() { iframeResize() });