views:

15457

answers:

9

Hi all,

I am opening my blog page in my website, problem is i can give width to iframe but height should be dynamic so that there is no scroll bar in iframe and it looks like a single page...

i have tried various javascripts to calculate height of content but all of them gives access denied permission and of no use.

my question is can we use ajax to calculate height or may be php.

thanks in advance

A: 

Try using scrolling=no attribute on the iframe tag. Mozilla also has an overflow-x and overflow-y css property you may look into.

In terms of the height, you could try height=100% also on the iframe tag.

Gary Green
height=100% does nothing.
flavour404
+1  A: 

Fitting IFRAME contents is kind of an easy thing to find on google. Here's one solution:

<script type="text/javascript">
function autoIframe(frameId) {
   try{
      frame = document.getElementById(frameId);
      innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document;
      objToResize = (frame.style) ? frame.style : frame;
      objToResize.height = innerDoc.body.scrollHeight + 10;
   }
   catch(err){
      window.status = err.message;
   }
}
</script>

This of course doesn't solve the cross-domain problem you are having... setting document.domain might help if these sites are in the same place. I don't think there is a solution if you are iframe-ing random sites

Scott Evernden
You're missing a unit on the height assignment, ie 'px'. Doesn't this cause a failure in standards mode?
Crescent Fresh
yeah for sure ... mybad
Scott Evernden
+3  A: 

You can do this with JavaScript.

document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px";
Anders S
The script confuses me. I like to practise with a real site: mathsearchun.blogspot.com/. Is the "id" the innermost div "HTML3" or the outermost div "outer-wrapper"? I got errors such as "contentWindow is undefined" and "document.getElementById("id") is null", in Firebug. What do they mean?
Masi
The element you want to get is the iframe, amazon in your case I guess. "contentWindow is undefined" probably means that the element you grabbed doesn't have that property/element.You need to use document.getElementById("amazon") to get your iframe.
Anders S
+7  A: 

To directly answer your 2 subquestions: No, you cannot do this with Ajax, nor can you calculate it with PHP.

What I have done in the past is use a trigger from the iframe'd page in window.onload (NOT domready, as it can take a while for images to load) to pass the page's body height to the parent.

<body onload='parent.resizeIframe(document.body.scrollHeight)'>

Then the parent.resizeIframe looks like this:

function resizeIframe(newHeight)
{
  document.getElementById('blogIframe').style.height = parseInt(newHeight) + 10 + 'px';
}

Et voila, you have a robust resizer that triggers once the page is fully rendered with no nasty contentdocument vs contentWindow fiddling :)

Sure, now people will see your iframe at default height first, but this can be easily handled by hiding your iframe at first and just showing a 'loading' image. Then, when the resizeIframe function kicks in, put 2 lines extra inthere that will hide the loading image, and show the iframe for that faux Ajax look.

Ofcourse, this only works from the same domain, so you may want to have a proxy PHP script to embed this stuff, and once you go there, you might aswell just embed your blog's RSS feed directly into your site with PHP.

SchizoDuckie
I'm using iframe to load pages. My iframe is in the main page which does not re-load once loaded. Only the pages in iframe changes based on the link clicked from main page that target the iframe. How do I adjust height of iframe in this case.
this. __curious_geek
+1  A: 

Not a question but more teaser for those that require iframes that dynamically adjust in height. For example, assume an iframe that displays a page containing tabbed content. One tab may contain content that is larger than the next tab. Do we therefore need to add an event listener in this situation or some function that will resend the adjusted page size to the parent?

A: 

Below is my onload event handler. I use an IFRAME within a jQuery UI dialog. Different usages will need some adjustments. This seems to do the trick for me (for now) in IE8 and FF3.5. It might need some extra tweaking but the general idea should be clear. Anyone knows a simpler more elegant solution?

    function onLoadDialog(frame) {
    try {
        var body = frame.contentDocument.body;
        var $body = $(body);
        var $frame = $(frame);
        var contentDiv = frame.parentNode;
        var $contentDiv = $(contentDiv);

        var savedShow = $contentDiv.dialog('option', 'show');
        var position = $contentDiv.dialog('option', 'position');
        // disable show effect to enable re-positioning (UI bug?)
        $contentDiv.dialog('option', 'show', null);
        // show dialog, otherwise sizing won't work
        $contentDiv.dialog('open');

        // Maximize frame width in order to determine minimal scrollHeight
        $frame.css('width', $contentDiv.dialog('option', 'maxWidth') -
                contentDiv.offsetWidth + frame.offsetWidth);

        var minScrollHeight = body.scrollHeight;
        var maxWidth = body.offsetWidth;
        var minWidth = 0;
        // decrease frame width until scrollHeight starts to grow (wrapping)
        while (Math.abs(maxWidth - minWidth) > 10) {
            var width = minWidth + Math.ceil((maxWidth - minWidth) / 2);
            $body.css('width', width);
            if (body.scrollHeight > minScrollHeight) {
                minWidth = width;
            } else {
                maxWidth = width;
            }
        }
        $frame.css('width', maxWidth);
        // use maximum height to avoid vertical scrollbar (if possible)
        var maxHeight = $contentDiv.dialog('option', 'maxHeight')
        $frame.css('height', maxHeight);
        $body.css('width', '');
        // correct for vertical scrollbar (if necessary)
        while (body.clientWidth < maxWidth) {
            $frame.css('width', maxWidth + (maxWidth - body.clientWidth));
        }

        var minScrollWidth = body.scrollWidth;
        var minHeight = Math.min(minScrollHeight, maxHeight);
        // descrease frame height until scrollWidth decreases (wrapping)
        while (Math.abs(maxHeight - minHeight) > 10) {
            var height = minHeight + Math.ceil((maxHeight - minHeight) / 2);
            $body.css('height', height);
            if (body.scrollWidth < minScrollWidth) {
                minHeight = height;
            } else {
                maxHeight = height;
            }
        }
        $frame.css('height', maxHeight);
        $body.css('height', '');

        // reset widths to 'auto' where possible
        $contentDiv.css('width', 'auto');
        $contentDiv.css('height', 'auto');
        $contentDiv.dialog('option', 'width', 'auto');

        // re-position the dialog
        $contentDiv.dialog('option', 'position', position);

        // hide dialog
        $contentDiv.dialog('close');
        // restore show effect
        $contentDiv.dialog('option', 'show', savedShow);
        // open using show effect
        $contentDiv.dialog('open');
        // remove show effect for consecutive requests
        $contentDiv.dialog('option', 'show', null);

        return;
    }

    //An error is raised if the IFrame domain != its container's domain
    catch (e) {
        window.status = 'Error: ' + e.number + '; ' + e.description;
        alert('Error: ' + e.number + '; ' + e.description);
    }
};
nelis
A: 

Here's my solution to the problem using MooTools which works in FF 3.6, Safari 4.0.4 and IE7:

var iframe_container = $('iframe_container_id');
var iframe_style = {
    height: 300,
    width: '100%'
};
if (!Browser.Engine.trident) {
    // IE has hasLayout issues if iframe display is none, so don't use the loading class
    iframe_container.addClass('loading');
    iframe_style.display = 'none';
}
this.iframe = new IFrame({
    frameBorder: 0,
    src: "http://www.youriframeurl.com/",
    styles: iframe_style,
    events: {
        'load': function() {
            var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document;
            var h = this.measure(function(){
                return innerDoc.body.scrollHeight;
            });         
            this.setStyles({
                height: h.toInt(),
                display: 'block'
            });
            if (!Browser.Engine.trident) {
                iframe_container.removeClass('loading');
            }
        }
    }
}).inject(iframe_container);

Style the "loading" class to show an AJAX loading graphic in the middle of the iframe container. Then for browsers other than IE, it will display the full height IFRAME once the loading of its content is complete and remove the loading graphic.

tru10000
A: 

The trick is to acquire all the necessary iframe events from an external script. For instance, you have a script which creates the iFrame using document.createElement; in this same script you temporarily have access to the contents of the iFrame.

var dFrame = document.createElement("iframe");
dFrame.src = "http://www.example.com";
// Acquire onload and resize the iframe
dFrame.onload = function()
{
    // Setting the content window's resize function tells us when we've changed the height of the internal document
    // It also only needs to do what onload does, so just have it call onload
    fobj.contentWindow.onresize = function() { dFrame.onload() };
    dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px";
}
window.onresize = function() {
    dFrame.onload();
}

This works because dFrame stays in scope in those functions, giving you access to the external iFrame element from within the scope of the frame, allowing you to see the actual document height and expand it as necessary. This example will work in firefox but nowhere else; I could give you the workarounds, but you can figure out the rest ;)

Soup d'Campbells
Trigger happy on the response. Scott above uses a similar script, but the inclusion of contentWindow.onresize allows you to resize the iframe if its contents change. It's also useful for fluid width iframes.
Soup d'Campbells
A: 

Soup d'Campbells, the sample you have isn't working for me in FF when it comes to the resizing of the iframe if its contents change (after reload). Also, there is a variable fobj being used not declared in the sample code shown. I changed it to dFrame and still no go. Any idea how to get the iFrame to resize if it's internal document size changes?

Alex