Use JQuery to adjust the iframe height

Although frame is generally not recommended on most of the web pages, iFrame can still be useful in some occasions, especially as an Ajax alternative. One strength of Ajax is that it greatly reduces (or at least it appears so) the page response time by only changing a small part of the page. Using Ajax to submit a form is a great example. This usability improvement doesn’t come free though. In order to use Ajax to send the form data back to the server, the JavaScript code has to be written to collect the form data and append them to the request URL as GET or POST parameters. Frameworks like JQuery or Prototype make this process a lot easier.

However there is some limitation to use Ajax to post a multi-part form. Although it might be possible, it is definitely not a clean implementation, and it is not supported by most of the browsers. In this case, iFrame may be a good alternative. The inner frame page will handle the multi-part form and the parent page will have the similar Ajax effect. That being said, iFrame’s biggest problem is that its width and height are set right from the start and it won’t adjust based on the source content. This will leave the ugly scrolling bars around the iFrame, or some content will be hidden if the scroll bar is disabled. For most of the pages, the width is somewhat less of a problem but the height is harder to control and set correctly.

The good news is there are ways to dynamically adjust the height of the iFrame based on the inner content. There are different ways to achieve this using JavaScript. I found this approach is the best:

Using jQuery, we can add the following code in the iframe source content:

<script type=”text/javascript”>
$(document).ready(function() {
var theFrame = $(“#iFrameToAdjust”, parent.document.body);
theFrame.height($(document.body).height() + 30);
});
</script>

The JavaScript will get the iframe object from the parent DOM and change its height according to the size of the current document after the document is loaded (very important to get the true size). I like it because it is less intrusive to the page where the iframe is on, and the iframe source kind of “take care of its own size” when being displayed. If the source page is displayed as regular page, there simply will not be any adjustment. With the help of jQuery the code is quite clean and simple. Of course the iframe source has to be an internal page and the developer has the permission to add the code.

From my testing result, this works in FF2, IE7 and Opera 9.25, not in Safari 3.1 for Windows though.

Some updates:

I found it work better to put the JavaScript which adjusts the frame height in the body onLoad attribute. Basically “ready” function will be kicked off when the DOM is loaded, at which point the page may or may not be completely loaded. The onLoad event will be a better bet in this case since we need the actual size of the page including all the images.

This entry was posted in javascript. Bookmark the permalink.

23 Responses to Use JQuery to adjust the iframe height

  1. Jim G. says:

    <>

    For even better results, you might want to use jQuery’s ‘Dimensions’ plug-in.

  2. mvc says:

    Im having problems making this work on IE7. It doesn’t resize

    any ideas why?

    Thanks

  3. Cory says:

    This also is working in firefox but not IE7 or 8 for me as well (it doesn’t resize).

  4. 1.618 says:

    mvc and Cory,

    Is the iframe src coming from a different domain? For example, the iframe is on a page of “abc.com/page1.htm”, and iframe src is “xyz.com/page2.htm”. In this scenario JavaScript in page2.htm won’t be able to change the iframe on page1.htm.

    Update:
    Pardon me for the ignorance. You did mention it works in FF. This is weird. Works in IE for me. Any chance you can post some code here?

  5. Cory says:

    Thanks for getting back to us on this issue. In my case the iframe src is not coming from a different domain. By the way in actuality I am using this on an object and not an iframe (I’m trying to stay away from iframes because I am trying to keep my page XHTML 1.1 (Strict)).

    Either way, in my case it doesn’t resize in IE whether I use an iframe or an object (It works in FF, Google Chrome, and Apple Safari).

    This code is contained in the “iframe / object source file” (named displayhtmlbody.cfm)
    —————————————————————————————

    $(document).ready(function(){

    testheight = $(document).height() + 4 +’px’;
    testwidth = $(document).width() + 4 + ‘px’;

    theFrame = $(“#test”, parent.document.body);
    theFrame.height(testheight);
    theFrame.width(testwidth);
    });

    —————————————————————————————

    The file that calls the iframe / object uses the following code:
    —————————————————————————————

    <!—

    —>

    —>
    —————————————————————————————

    Also of note is that it doesn’t make a difference if I change the jQuery code from a “ready” function to one that is called via body onLoad (IE still doesn’t resize). I’m glad it’s working for you in IE, It’s just strange that it doesn’t seem to be working for me or mvc.

    Let me know if I can provide any more info.
    If supplying this snippet of code doesn’t seem to help, maybe you can post a
    demo that I can try loading on my own machine.

    Thanks,
    Cory

  6. Cory says:

    It looks like it messed up the code I posted for the page that loads the object.
    Let me try again:

    I have an If IE statement that loads the object this way:

    If it is any other browser it loads the object this way:

  7. Cory says:

    It looks like posting code in comments doesn’t work so well.

    Anyway, I set up a demo page where it fails in IE (but works in other browser) for me :
    sandbox.freecoldfusionhosting.com/members/c/cwadams/iframe/resizetest

    You can view the source of the child and parent pages their.

  8. 1.618 says:

    Cory,
    I tried your code it seems in IE, JQuery can’t locate the object through $(‘#id’, parent.document.body). Not sure if this is IE’s fault or JQuery’s. Judging by the fact it works in FF and Chrome it probably is the former.
    Any chance to use iframe if it is IE, using the conditional comment? Other than this I haven’t been able to find any workaround.

  9. Cory says:

    Thanks for checking out my code.
    Yes, for now I am using a conditional comment to load an
    iframe in IE and an object in any other browser.

    I went back and rechecked my code and your solution does in fact
    work in both IE and other browsers for Iframes (it just fails on objects in IE).

    Anyway, I think this problem is IE’s fault on the way that it handles objects.
    This is an educated guess, but it appears IE doesn’t handle objects like iframes
    as they appear to be handled in other browsers.

    Before I found your post I was resizing iframes using this method:

    In the parent page that loads the iframe:
    ——————————————————————————
    function resizeIframe(newHeight,newWidth)
    {
    document.getElementById(‘test’).style.height = parseInt(newHeight, 10) + ‘px’;
    document.getElementById(‘test’).style.width = parseInt(newWidth, 10) + ‘px’;
    }
    ——————————————————————————

    In the iframe:
    ——————————————————————————
    function Resize()
    {
    testheight = $(document).height() + ‘px’;
    testwidth = $(document).width() + ‘px’;

    parent.resizeIframe(testheight,testwidth);
    }

    ——————————————————————————

    This method also worked on iframes in both IE and other browsers.
    However, it produced the following error in IE when used with objects (worked in other browsers):

    “object doesn’t support this property or method”

    So it seems like IE can’t handle calls to parent functions from inside an object.
    This may explain why your code fails to resize the object when in IE as it is doing a call to parent.document.body

    Anyway, I have looked into many ways of working around this, but haven’t had any luck. I even tried trying to somehow pass the heigh and width variables from the object to the parent page by the use of session variables (as shown here: http://www.thomasfrank.se/sessionvars.html). That only worked if the page was reloaded after the frame had finished loading (which makes sense).

    I also tried using ajax to load an external page into a div, as shown below (where ID is the id of the div):
    ——————————————————————————
    $.ajax({
    url: “externalpage.html”,
    cache: false,
    success: function(html){
    $(“#id”).append(html);
    }
    });
    ——————————————————————————

    Unfortunately this messed up the CSS within the document by acquiring the CSS of the main page.
    And I found no way of preventing this.

    Just putting this out there in case some one is looking for an alternative way of doing this.
    For now I have to “give up” and use an Iframe for IE.

    Thanks again.

  10. John says:

    Cory … maybe I’m being dim, but in your original method of resizing iframes quoted in 9. above, why do you concatenate ‘px’ to the height and width parameters in function Resize(), only to apparently strip it off again – via parseInt() – and then stick it straight back on again in function resizeIframe() ?? Why not simply pass the numeric values and add the ‘px’ in resizeIframe() only ??

  11. Regina says:

    John–

    When testing for what works with any given browser on different systems— one tries many different things. When we find things that work– we do not undo — what is working. You can never tell which browser is going to scream- at what. Cory– tests a lot.

    Q…

  12. Pingback: 8degrees of vaughan rowsell » Dynamically resize an iframe depending on it’s content

  13. Jay says:

    The IE problem seems to be because the value returned by $(document.body).height() isn’t the actual height of the page in IE. Strip this part out and throw it into an alert in your child frame to see what I mean.

    What seems to fix it for IE is adding an ID of the div content wrapper, which IE seems to be able to sort of measure (I say sort of, because it’s also a few pixels out).

    So:

    $(document.body).height()

    becomes

    $(‘#wrapperId’, document.body).height()

  14. annie says:

    I like this code but it only seems to work if the parent doc and the iframe are hosted on the same web server. What if they are on different servers? Is it still possible?

  15. Kapil says:

    Hi,

    I am facing the issue in FF3.6.10, but it is working fine in IE.

    Please can you suggest on this.

    Thanks,
    Kapil

  16. Al says:

    Annie, by loading javascript from a different web server, you run the risk of cross domain issues, no?

  17. Ericb says:

    So, someone seems to have finally come with a cross-domain / cross-browser solution for dynamically resizing iframes.
    (and generally secure cross-site scripting)
    It involves a jquery plugin, jQuery postMessage, and a couple of functions to place
    both on the parent page and the body of the called iframe.

    details and plugin are here :
    http://benalman.com/projects/jquery-postmessage-plugin/

    cross-site iframe example here :
    http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

  18. dice says:

    Someone please help me.
    I m using one iframe contain 6 tabs with different forms having different heights(all this are in one file allform.php),And i dont want srollbar.Is it posible apply different heights to single iframe asper height?
    Please Help me.

  19. Tuan Bui says:

    we are using cross-site scripting jquery-postmessage-plugin in the embed iframe solution for our survey website http://www.mobosurvey.com and it works great.

  20. Sarah Bird says:

    Planning to use jquery-postmessage-plugin in my latest project http://www.surveyrobo.com/. I am hoping that I don’t face any compatibility issues. Any tips for testing it? Thanks for sharing it though. Count me in your fans :)Waiting for your response.

  21. idham says:

    Thanks, i found your code work perfectly.
    Before i use :
    $(“#cframe1″).height($(“#cframe1″).contents().find(“html”).height());
    $(‘#cframe1′).css({‘height’ : iframeHeight + ‘px’});
    but not working, use
    if($.browser.mozilla)
    {
    var heightDiv = jQuery(“iframe”,top.document).contents().attr(“height”)+”px”;
    jQuery(“#cframe1″,top.document).css({height:heightDiv});
    }
    else if($.browser.opera || $.browser.safari || $.browser.msie)
    {
    var heightDiv = jQuery(“iframe”,top.document).height();
    jQuery(“#cframe1″,top.document).css({height:heightDiv});
    }
    also not working.

  22. idham says:

    Thanks, i found your code work perfectly.
    Before i use :
    $(“#cframe1″).height($(“#cframe1″).contents().find(“html”).height());
    $(‘#cframe1′).css({‘height’ : iframeHeight + ‘px’});
    but not working, use
    if($.browser.mozilla)
    {
    var heightDiv = jQuery(“#cframe1″,top.document).contents().attr(“height”)+”px”;
    jQuery(“#cframe1″,top.document).css({height:heightDiv});
    }
    else if($.browser.opera || $.browser.safari || $.browser.msie)
    {
    var heightDiv = jQuery(“#cframe1″,top.document).height();
    jQuery(“#cframe1″,top.document).css({height:heightDiv});
    }
    also not working.

Comments are closed.