I'm having an issue resizing an iframe to fit the content located within the frame'd page. I used a suggestion I found here to resize the frame dynamically.
In my frame'd pages I have
<body onload='parent.resizeIframe(getDocHeight())'>
function getDocHeight() {
var D = document;
alert(D.URL);
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
}
And in the page containing the iframe I have this
function resizeIframe(newHeight) {
var showsFrame = document.getElementById('frm');
showsFrame.style.height = parseInt(newHeight) +'px';
}
The function is getting called correctly by each frame'd page, but for some reason the 'newHeight' parameter being passed is keeping the largest height value. For example if I have 2 frame'd pages one with a scroll height of 300px and the other with 500px. When I first click my link to load the 300px page it works fine, but if I click the link to the 500px page and then try and come back to the 300px page, the value of 'newHeight' remains at 500. Any ideas? TIA
I found the issue I was having for anyone else that is experiencing the same thing. Because my frame'd pages didn't have much content the scrollHeight was reporting the length of the entire document and not cutting where my content stopped. Instead of trying to calculate scrollHeight, I simply looked for the offsetHeight which was the correct height I was looking for. Firebug is a nice tool to inspect the DOM of each page and see the values of each attribute without having to write debugging messages. I put this line in every frame'd page
<body onload='parent.resizeIframe(getDocHeight())'>
and in a separate js file I have this code to calculate the height.
function getDocHeight() {
var D = document;
return Math.max(
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
);
Try it with JQuery
function resizeIframe(newHeight) {
$('#iframeId').attr('height',newHeight);
or
$("#frameId").height(newHeight);
}
Related
I've googled a bit and there were a few leads, but I couldn't get any of those leads to work:
I have a page that has an iframe with the src pointing to an external page (cross domain). When the child/iframed page loads, it posts a message of its height. I put a console.log of the height in the javascript. If I open that page in a separate window (type the iframe's src URL in a separate tab, in other words), the console logs the expected height.
However, when I open the parent page with the iframe, the console logs either 0 or a very incorrect value of 150. I've looked through the css and html, and I don't have any specifications of 150.. Anyone have a clue what's going on here?
Abstracted code:
Parent HTML:
...
<iframe src="example.childpage.com" scrolling="no" frameBorder="0"></iframe>
...
Parent Javascript:
...
$(document).ready(function(){
window.addEventListener('message', function(m){
var messageData = m.data;
if(messageData.type=='document-loaded' &&
messageData.hasOwnProperty('height'){
resize_iframe(messageData.height); //function defined else where
//and works
};
});
...
IFrame Javascript:
...
$(document).ready(function(){
var body = document.body;
var html = document.documentElement;
var maxHeight = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
//Logs height correctly when opened in a separate window but not when
//iframed
console.log("POSTING HEIGHT", maxHeight);
window.parent.postMessage({'type':'document-loaded', 'height': maxHeight},
PARENT_HOST_URL); //PARENT_HOST_URL defined elsewhere
});
...
I realize I have a mixture of jquery and vanilla javascript here; I've done both $(document).height() and the Math.max() shown above to get the height, but both ways still have the same issue.
Much thanks!
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';
}
I had a function that looped through not-yet-accessible elements and called $(element).hide() on them -- which sets the style display: none.
Turns out calculating the height of an element is respective of its visibility on the actual page, regardless of it being in an iframe. So the browser couldn't see it, so the height was being miscalculated (still weird it was returning a random 150px value). That explains why it was calculating correctly on a separate page.
Instead of doing hide(), I just set the visibility to hidden and that fixed my issue of getting the incorrect heights.
I'm having a very strange occurrence when using an IFrame and jQuery.Contents.
We have a number of reports that are built in seperate pages, and a display page that uses jQuery Tabs to display a number of these pages at once.
These reports are of varying sizes based on the data and the inputs by the user, since they can vary we needed to dynamically set the height of the IFrame to be the height of the contents. To get the height of the contents I am using this following code :
var iframeHeight = $(this).contents().height();
iframeHeight += 50;
console.log(iframeHeight);
This code works fine on first load, but after the IFrame Postsback/Refreshes the iframeHeight that is logged is always 83px more than the previous height, regardless of the actual contents of the child page.
i.e. First report is 500px high,
Second report should be 300px high
but $(this).contents().height(); returns 583px.
Here is an example jsFiddle to demonstrate the problem. If you open the console and then click the JSFiddle Icon in the top left of the IFrame, you will notice that the logged height will be 83px more than the previous.
Is there anything that could explain this issue?
Am I miss-understanding how the jQuery.Contents function works?
If this will not work this way is there a better way to get the content height? (I've tried the height of the body + the height of the form object but this didn't work in IE).
Tested this in IE10 + Chrome Version 31.0.1650.57 m
Here is an implementation that seems to work (for expanding/shrinking contents..)
assuming that iframe's src is from the same domain and that there are not scripts that resize the iframe's contents once loaded
$(document).ready(function() {
$('#frameID').on('load', function () {
$('#ReportBuild').hide()
$(this).show();
var iframeHeight = $(this.contentDocument.documentElement).outerHeight(true);
$(this).css({ height: iframeHeight + 'px' });
this.contentWindow.onbeforeunload = function () {
$('.tabFrame').hide();
$('#ReportBuild').show();
}
});
});
Demo at http://jsfiddle.net/rq5S5/8/
With help I managed to finally find a solution, suggested examples worked on JSFiddle's but would not work when applied to my issue using ASP.NET controls generated on PostBack.
To handle this, on each of my Child pages I have wrapped the entire content inside a <div></div> and retrieved the height of this element.
Example :
<div id="ReportContent">
<!-- HTML Content -->
</div>
And the jQuery Code :
var iframeHeight = $(this).contents().find('#ReportContent').outerHeight(true);
This now works correctly for my problem in both IE10 and Google Chrome Version 31.0.1650.57 m
I'm writing a script that creates a popup that dims the screen behind the popup. I'm using JQuery's $("#dim").css("height", $(document).height()); to resize the div element in question, but it doesn't cover the master page area. Is there a way I can get the height of the WHOLE page and not just the child page?
EDIT: The problem may actually lie in the positioning, and not the size, of my div. I have it set to top:0, but maybe I need to move it using javascript?
Give this a shot:
var width = screen.availWidth;
var height = screen.availHeight;
Since .outerHeight() isn't supported for window or document, you'll have to add the padding to the height() yourself.
$("#dim").css( "height", $(document).height() + 2*parseInt($(document).css("padding"),10) );
I have a page that loads another page(url) onto it. The problem is that the iframe page does not fit well in the outer page. How can I reduce the size of the iframe page having the content of the iframe page intact? I do not wish to have scroll bars.
Unfortunately you can't really scale an iframe so that its contents change their size. To the browser, the iframe is a window onto another rendering context which has its own layout according to its own CSS. You are at the mercy of how the content inside the iframe is laid out.
If the iframe URL is from a different site and you can't modify it, then you can't really do anything.
If you can modify the page that's displayed within the iframe, well I'd assume you wouldn't be asking.
See the answer here ( How can I scale the content of an iframe? ). I'm using it and it works on FF, Chrome a little flakey.
You could try expanding the width/height of the iframe and checking the clientWidth vs iframe width. If they're equal, there's no scrollbar, otherwise there is.
Use a midpoint approach for efficiency. In sudo-code:
dx = iframe.width;
while (dx > 1) {
previous = iframe.width
if( iframe.width - iframe.clientWidth > 0 ) {
iframe.width += dx*2;
} else {
iframe.width -= dx/2;
}
dx = Math.abs(previous-iframe.width)
}
Here's what i have so far:
function loadOff(){
$(document).ready(function(){
$("#eLoader").ajaxStop(function(){
$(this).hide();
$("#eventsContent").show();
var h = document.body.scrollHeight;
$("#bodyBackground").css("height",h+100+"px");
$("#sidePanel1").css("height",h-105+100+"px");
$("#bottom").css("top",h+100+"px");
});
});
}
This is a callback function for a JQuery ajax function, basically what is does is when all ajax is finished .ajaxStop() it hides the loader then shows the content.
The problem i am having is adjusting bodyBackground, sidePanel, and bottom to fit the content. I dont care to have it elastic and retract for short content at this point, i would just like it to extend to proper positioning based on content length.
All divs are absolutely positioned. The numbers in the function are broken down simply to make it easy to explain. -105 is the offsetTop of that element and +100 is the margin between the end of the content and the elements.
if there is a better, more efficient way to achieve this outcome, please, do tell.
Thanks.
Based on your code, the only thing you ought to see is the top 105px of #sidePanel1. Is that your intent? (h = the bottom of the window, according to your code.)
Sticking with the JQuery patterns, you would use
var h = $(window).height();
Maybe you're looking for this instead of the browser window's height? It will get the height of the content element.
$("#eventsContent").outerHeight();