views:

72

answers:

3

I have a Help page, help.php that I am loading inside an iframe in main.php How can I get the height of this page once it has loaded in the iframe?

I am asking this because I can't style the height of to iframe to 100% or auto. That's why I think I need to use javascript.. I am using jQuery

CSS:

        body { margin: 0; padding: 0; }
        .container { 
            width: 900px;
            height: 100%;
            margin: 0 auto;
            background: silver; 
        }
            .help-div { 
                display: none;
                width: 850px; 
                height: 100%;
                position: absolute;
                top: 100px;
                background: orange;     
            }   
        #help-frame {
            width: 100%; 
            height: auto;
            margin:0; padding:0;
        }

JS:

        $(document).ready(function() {      
            $("a.open-help").click(function() {
                $(".help-div").show();
                return false;
            })
        })

HTML:

    <div class='container'>

        <!-- -->
        <div class='help-div'>
            <p>This is a div with an iframe loading the help page</p>
            <iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
        </div>  

        <a class="open-help" href="#">open Help in iFrame</a>

        <p>hello world</p>
        <p>hello world</p>
        <p>hello world</p>
        <p>hello world</p>
        <p>hello world</p>

    </div>
A: 

I'm not sure what, if any, events in the iFrame are returned to the parent page (I'm fairly sure that none will make it back, but I'm not entirely certain). All I can think of to suggest in this matter is that in the function call to load the help.php page you also implement a call to:

$('#iframeID').height();

Which will, obviously, return the height of the element (in the parent page). You can then use that as a console.log(/*...*/), or an alert(/*...*/) or in whatever way you'd like. The problem remains, though, that I don't think that there's a way of responding to a change, or load, event in the iFrame itself.

David Thomas
Hi I have problems with styling the height for the div where the the iframe goes. I set all heights to 100% but the iFrame does not show entirely. So your example returns 900px, even if the height is about 5000px now. That's why I would like to get the height once it is loaded.
FFish
@FFish, I've implemented an iframe-container page on my localhost (for a bookmark aggregator page), and I've found that if you apply height directly to the iFrame (with CSS) that height is obeyed. The parent `div` should be left with the default `height: auto` and it *will* expand (it does in my case, with the `<!DOCTYPE html>` declaration, anyway) as necessary.
David Thomas
A: 

The less complicated answer is to use .contents() to get at the iframe. Interestingly, though, it returns a different value from what I get using the code in my original answer, due to the padding on the body, I believe.

$('iframe').contents().height() + 'is the height'

This is how I've done it for cross-domain communication, so I'm afraid it's maybe unnecessarily complicated. First, I would put jQuery inside the iFrame's document; this will consume more memory, but it shouldn't increase load time as the script only needs to be loaded once.

Use the iFrame's jQuery to measure the height of your iframe's body as early as possible (onDOMReady) and then set the URL hash to that height. And in the parent document, add an onload event to the iFrame tag that will look at the location of the iframe and extract the value you need. Because onDOMReady will always occur before the document's load event, you can be fairly certain the value will get communicated correctly without a race condition complicating things.

In other words:

...in Help.php:

var getDocumentHeight = function() {
    if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady
        location.hash = $('body').height(); 
        // at this point the document address will be something like help.php#1552
    }
};
$(getDocumentHeight);

...and in the parent document:

var getIFrameHeight = function() {
    var iFrame = $('iframe')[0]; // this will return the DOM element
    var strHash = iFrame.contentDocument.location.hash;
    alert(strHash); // will return something like '#1552'
};
$('iframe').bind('load', getIFrameHeight );
Andrew
Hi Andrew so far very good help here. contents() works great, but I still need to test it with a bandwidth throttler. Maybe you can use the innerHeight() property. I have a problem in FF (OSX) using your solution putting the height in the hash. FF seems to keep on loading the getDocumentHeight() function in an infinitive loop? Safari is fine..
FFish
Interesting. I've added a check that prevents the setting of the hash if there's already a value there. You may need to tweak this if you are loading Help.php with a hash value (e.g. `<iframe src="../Help.php#introduction" />`)
Andrew
By the way, Assuming you can adjust for the difference in height, you probably needn't use the hash to communicate out of the iframe. If you do use the hash method, putting a `sleep(5)` in your Help.php should also be a good way of testing for any race conditions. If the iframe does somehow fire `onLoad` before `onDOMReady`, it should show up here.
Andrew
A: 

ok I finally found a good solution:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

Because some browsers (older Safari and Opera) report onload completed before CSS renders you need to set a micro Timeout and blank out and reassign the iframe's src.

$('iframe').load(function() {
    setTimeout(iResize, 50);
    // Safari and Opera need a kick-start.
    var iSource = document.getElementById('your-iframe-id').src;
    document.getElementById('your-iframe-id').src = '';
    document.getElementById('your-iframe-id').src = iSource;
});
function iResize() {
    document.getElementById('your-iframe-id').style.height = 
    document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px';
}
FFish