Shortly after writing a quick guide on how to set IFRAME height based on size of remotely loaded content an error came to light where Chrome and Firefox would either keep growing the iframe with after each load, or would set the iframe too large if subsequent content was shorter than the initial content.
I wasn’t able to determine the exact cause of the problem, but I implemented a work around which cured the problem. I’ve extracted the core code as a template to resolve the problem. Basically we call a function periodically, and try to see if the IFRAME height remains constant. If it does, then assume it’s stopped changing, and call the local resizing function with the hopefully correct height.
REMOTE.COM/REMOTE.HTML
var IFRAME={};
function isHeightStatic(h, x){
IFRAME.resizeHeight[IFRAME.resizeHeight.length] = h;
// Test to see if h has changed over last x iterations.
for (var i=IFRAME.resizeHeight.length-1; i >= IFRAME.resizeHeight.length-x; i--) // don't test last element, as we just added it
if (i < 0 || IFRAME.resizeHeight[i]!=h) return false; //value is or may still be changing
return true;
}
function iframeResizePipe(){
// noticable when subsequent content is shorter.
//var height = jQuery(document.body).height();
var height = document.body.parentNode.scrollHeight;
var heightStatic = isHeightStatic(height,4); //same height for 1 second? (4 * 250ms)
if (IFRAME.resizeHeight.length>48 || heightStatic) //Iterate 50 times at 250ms delay = 12 seconds load time
clearInterval(IFRAME.resizeTimer);
if (!heightStatic){
// Going to 'pipe' the data to the parent through the helpframe..
var pipe = document.getElementById('helpframe');
if ( pipe == undefined ) return;
// Cachebuster a precaution here to stop browser caching interfering
pipe.src = 'http://local.com/helper.html?height=height&cacheb='+Math.random();
}
}
jQuery(document.body).ready( function(){
// Ready event seems to trigger before remote images are loaded. When images don't speficy height,
// cause page height to be calculated wrongly (from Larger Images).
// So ping every 250ms to see if the height has increase, and reset the iframe size.
IFRAME.resizeTimer = setInterval('iframeResizePipe()', 250);
});
NOTE: Code extracted from working code, based around jQuery, which has been commented out, with the exception of the onload handler which is performed by jQuery above.
Hope this helps a little at least.