PDA

View Full Version : jQuery get height of iframes source.



keyboard
01-05-2013, 10:18 AM
Greetings all!
I'm trying to get the height of the source of an iframe, so that I can resize the iframe so that it fits this...

I've tried using

$('#forum_iframe').contents().height()+'px';

But this won't work in FF for some reason...
Any suggestions?

molendijk
01-05-2013, 11:46 AM
I haven't tried yet to do it with jQuery, but this (http://mesdomaines.nu/eendracht/iframe_resize_better/iframe_resize.html) is an alternative.

Beverleyh
01-05-2013, 12:13 PM
This auto-height Iframe plugin for jQuery might be useful, if only to investigate their method : https://github.com/Sly777/Iframe-Height-Jquery-Plugin

molendijk
01-05-2013, 04:14 PM
The plugin seems to work alright, but I don't see an animated version. Does jQuery haved something like this (http://mesdomaines.nu/eendracht/iframe_resize_animation_constructor_final/iframe_resize_animation_constructor.html) or this (http://mesdomaines.nu/eendracht/iframe_resize_animation_conclusive_final/animated_autoresize_iframe.html)? I made them some time ago.

keyboard
01-07-2013, 08:16 AM
I looked at both your suggestions... then I remembered a bit of information that I forgot -

With the code I posted, or this code -

function changeHeight(iframe) {
try {
iframe = document.getElementById(iframe);
var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
if (innerDoc.body.offsetHeight) {
/*iframe.height = */alert(innerDoc.body.offsetHeight + 32); //Extra height FireFox
} else if (iframe.Document && iframe.Document.body.scrollHeight) {
/*iframe.height = */alert(iframe.Document.body.scrollHeight);
}
}
catch(err) {
alert(err.message);
}
}
It's only Firefox that will not alert it correctly. HOWEVER - Sometimes it does work, normally on the first page load... Does this suggest anything?

jscheuer1
01-07-2013, 11:36 AM
First off, Firefox often will not cross script locally. So it needs to be tested on a server or virtual server like XAMP, WAMP, etc.

Second, using the iframe as an element is the hard way. If you use it as a window, it's document is window_reference.document in all browsers, so none of that testing business that's required when the iframe is used as an element. The only trick is obtaining the reference to the iframe which corresponds to it as a window in such a way that all browsers agree upon it. I believe that's by number. So, let's say it's the only iframe on the page:


alert(jQuery(window.frames[0].document).height());

should do it (untested).

The other way of obtaining a reference to the iframe as a window is by it's name attribute. So let's say you have an iframe with a name attribute of "myframe":


alert(jQuery(window.frames['myframe'].document).height());

But I think the number method is more cross browser.

Now of course you have to wait until the onload event of the iframe has fired before checking for this, so assuming the first scenario (by number), this might be fun playing with to see how it works out:


jQuery(function($){
var $iframe = $('iframe').eq(0);
$iframe.load(function(){
$iframe.animate({height: $(window.frames[0].document).height()}, 600);
});
$iframe.data('load', function(){$iframe.trigger('load');});
});

The last line simply creates a reference in case you want to fire the load function manually with a button or link:


$('#mybutton').click($('iframe').eq(0).data('load'));

All of this is untested though, and knowing jQuery visa vis straight javascript like I do, in this sort of situation, more of the duties might have to be carried out in ordinary javascript.

jscheuer1
01-07-2013, 12:38 PM
I tried it out. It needed some tweaks. This worked in limited testing:


<!DOCTYPE html>
<html>
<head>
<title>jQuery Resize Iframe</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
var $iframe = $('iframe').eq(0), ie = (function(){var ie; return (ie = /MSIE (\d+)/.exec(navigator.userAgent)) && ie[1] < 9 ? 5 : 0;})();
$iframe.load(function(){
$iframe.animate({height: $(window.frames[0].document.body).outerHeight(true) + ie}, 600);
});
$iframe.data('load', function(){$iframe.trigger('load');});
ie && $(window).load($iframe.data('load'));
});
</script>
</head>
<body>
<iframe name="myframe" src="frame1.htm" width="300" height="300" scrolling="auto" frameborder="1"></iframe><br>
<a href="frame1.htm" target="myframe">Frame1</a><br>
<a href="frame2.htm" target="myframe">Frame2</a><br>
</body>
</html>

molendijk
01-07-2013, 01:09 PM
Hi Keebs,
Your code produces the correct alerts on my machine (using FF), but doesn't seem to correctly resize the iframes. If you just want a simple script that works (no animation), you can do this:
main.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Setting Iframe Element Height to Iframe Content Height</title>



<script>
/* free code from dyn-web.com */

function getDocHeight(doc) {
doc = doc || document;
// from http://stackoverflow.com/questions/1145850/get-height-of-entire-document-with-javascript
var body = doc.body, html = doc.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
return height;
}

function setIframeHeight(id) {
var ifrm = document.getElementById(id);
var doc = ifrm.contentDocument? ifrm.contentDocument: ifrm.contentWindow.document;
ifrm.style.visibility = 'hidden';
ifrm.style.height = "10px"; // reset to minimal height in case going from longer to shorter doc
ifrm.style.height = getDocHeight( doc ) + 5+"px";
ifrm.style.visibility = 'visible';
}
</script>

</head>
<body ><div style="position: relative; margin: auto; width:100%">


<h1 style="margin-top: 10px; text-align: center">Setting Iframe Element Height to Iframe Content Height</h1>

<div style="position: relative; text-align: center; margin-bottom:10px">
<a href="javascript: void(0)" onclick="frames.some_name.location.replace('page1.html'); return false">page 1</a>
<a href="javascript: void(0)" onclick="frames.some_name.location.replace('page2.html'); return false">page 2</a>
<a href="javascript: void(0)" onclick="frames.some_name.location.replace('page3.html'); return false">page 3</a>
</div>

<div style="position: relative; margin: auto; width:400px; background:white; border: 1px solid black">
<iframe id="some_id" name="some_name" src="page1.html" style="width:100%; text-align: center" frameborder="0" scrolling="no" onload="setIframeHeight(this.id)"></iframe>
</div>

</div></body>
</html>
page1.html (first iframe):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>

</head>

<body style="font-family: verdana; font-size:12px; "><div>

<h2 style="text-align: center">PAGE 1<br>The height of this iframe is auto-adjusted to its content's height</h2>
<div style="text-align: center">
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page1.html'); return false">page 1</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page2.html'); return false">page 2</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page3.html'); return false">page 3</a>
</div>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.
</div></body>

</html>
page2.html (second iframe):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>

</head>

<body style="font-family: verdana; font-size:12px; "><div>

<h2 style="text-align: center">PAGE 2<br>The height of this iframe is auto-adjusted to its content's height</h2>
<div style="text-align: center">
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page1.html'); return false">page 1</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page2.html'); return false">page 2</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page3.html'); return false">page 3</a>
</div>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history. <BR><BR>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history. <BR><BR>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.
</div></body>

</html>
page3.html (third iframe)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>

</head>

<body style="font-family: verdana; font-size:12px; "><div>

<h2 style="text-align: center">PAGE 3<br>The height of this iframe is auto-adjusted to its content's height</h2>
<div style="text-align: center">
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page1.html'); return false">page 1</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page2.html'); return false">page 2</a>
<a href="javascript: void(0)" onclick="parent.frames.some_name.location.replace('page3.html'); return false">page 3</a>
</div>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.<BR><BR>

<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.<BR><BR>


<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.<BR><BR>


<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.<BR><BR>


<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.<BR><BR>


<br>The dog (Canis lupus familiaris), is a domesticated subspecies of the Gray Wolf, a member of the Canidae family of the order Carnivora. <br><br>The term is used for both feral and pet varieties. <br><br>The domestic dog has been one of the most widely kept working and companion animals in human history.

</div></body>

</html>
Tested and working with all modern browsers. (IE and Chrome only handle this well online).

molendijk
01-07-2013, 05:37 PM
For some reason, I hadn't noticed John's script when I submitted my last post.
It's a very nice script. I tested it in IE (down to IE7), Firefox, Google Chrome, Opera and Safari. The results were fine with each browser.
I would suggest 2 modifications though:
<iframe scrolling="no" ...
and:
document.body).outerHeight(true) + 5 + ie}, 600

keyboard
01-07-2013, 09:55 PM
Thanks for all those responses everyone!
Thanks for that suggestion John, I'll use that method to retrieve the height instead!

As for your post Arie, sometimes on my machine it works, others it doesn't.... Maybe it's just a problem with my computer. And yes, I know it won't resize, I commented that bit out of my code for testing purposes...

I think scrolling="no" is now depricated, and you have to use css instead... but point taken!


Thanks for all the help guys... I'll try it all out later this afternoon and see how I go :)

molendijk
01-07-2013, 10:13 PM
The scrolling attribute is obsolete all together, as is the frameborder attribute. But all browsers support it.
If you don't want them, see this (http://www.dynamicdrive.com/forums/entry.php?252-Replacing-iframe-attributes-with-javascript-%28HTML5%29).
Anyways, I think scrolling must not be allowed in order to avoid scroll bars to appear in an iframe that should be truly resized.

keyboard
01-07-2013, 10:17 PM
I agree that scrolling should be hidden... but can't you just use overflow:hidden; ?

molendijk
01-07-2013, 10:23 PM
I agree that scrolling should be hidden... but can't you just use overflow:hidden; ?
overflow:hidden works in all modern browsers except IE. So you need something for IE, which could be scrolling="no" if you don't care about validation (validation should not be a purpose on itself!!) or the script I referred to above.

jscheuer1
01-08-2013, 04:00 AM
The overflow: hidden; property/value pair works cross browser if assigned to the html and/or body elements of the page in the iframe.

An important note about what I said:



alert(jQuery(window.frames[0].document).height());

That needs to be:


alert(jQuery(window.frames[0].document.body).outerHeight());

And something else to be aware of (just as with any iframe resizing scheme) is that only works if the content that determines the height required by the window showing the page being loaded into the iframe is in the normal flow (position static or relative without going beyond the bottom) of the page. Absolute, relative, fixed, or floated content might cause problems, as can tables in some browsers.

You can choose trying to determine if there's anything like that on the remote page and/or look for things that have an offsetTop + offsetHeight that's greater than the document.body.offsetHeight (or the jQuery equivalents). But generally it's best not to use any of that stuff on the remote page.

jscheuer1
01-08-2013, 04:26 PM
Here's a working demo:

http://home.comcast.net/~jscheuer1/side/jqresizeiframe/iframe-top-2.htm

The overflow-y is hidden on the pages in the iframe for both the html and body elements. Nothing else is done to eliminate the scrollbar, that's apparently sufficient cross browser. I left the border at 1 because it shows the resizing more dramatically. If you want no border in IE 8 and less, you must use the deprecated border=0 attribute.

The code on that page should work with multiple iframes. All that's required is that they each have a class of "resize", which allows you to also have other iframes on the page without that class, those iframes will not resize. If you don't want the resize to be an animation, that's simple, let me know.

dklbwf
03-21-2013, 07:44 PM
John,

Your solution is 100% what I am looking for but it is not working IE for me....tested in ie7 but no luck. IE7 is around 95% of our enviornment. Attached screenshot of the 3 views and also is there a easy way to make the space disappear if the actual iframe content is 100% empty? Have emergency banner that will only be displayed when a message is made active and needing to stretch it in hieght without scrollbars according to content as there may be multiple messages at once.
4994
<!DOCTYPE html>
<html>
<head>
<title>jQuery Resize Iframe</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
var $iframe = $('iframe').eq(0), ie = (function(){var ie; return (ie = /MSIE (\d+)/.exec(navigator.userAgent)) && ie[1] < 9 ? 5 : 0;})();
$iframe.load(function(){
$iframe.animate({height: $(window.frames[0].document.body).outerHeight(true) + ie}, 600);
});
$iframe.data('load', function(){$iframe.trigger('load');});
ie && $(window).load($iframe.data('load'));
});
</script>
</head>
<body>
<iframe name="myframe" src="http://intranet-dev/deztest.cfm" width="300" height="300" scrolling="auto" frameborder="1"></iframe><br>
<a href="frame1.htm" target="myframe">Frame1</a><br>
<a href="frame2.htm" target="myframe">Frame2</a><br>
</body>
</html>



Thanks n advance,
I tried it out. It needed some tweaks. This worked in limited testing:


<!DOCTYPE html>
<html>
<head>
<title>jQuery Resize Iframe</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
var $iframe = $('iframe').eq(0), ie = (function(){var ie; return (ie = /MSIE (\d+)/.exec(navigator.userAgent)) && ie[1] < 9 ? 5 : 0;})();
$iframe.load(function(){
$iframe.animate({height: $(window.frames[0].document.body).outerHeight(true) + ie}, 600);
});
$iframe.data('load', function(){$iframe.trigger('load');});
ie && $(window).load($iframe.data('load'));
});
</script>
</head>
<body>
<iframe name="myframe" src="frame1.htm" width="300" height="300" scrolling="auto" frameborder="1"></iframe><br>
<a href="frame1.htm" target="myframe">Frame1</a><br>
<a href="frame2.htm" target="myframe">Frame2</a><br>
</body>
</html>

jscheuer1
03-21-2013, 08:38 PM
Try Arie's 2 tweaks to it from post #9 in this thread:

http://www.dynamicdrive.com/forums/showthread.php?72554-jQuery-get-height-of-iframes-source&p=289091#post289091


For some reason, I hadn't noticed John's script when I submitted my last post.
It's a very nice script. I tested it in IE (down to IE7), Firefox, Google Chrome, Opera and Safari. The results were fine with each browser.
I would suggest 2 modifications though:
<iframe scrolling="no" ...
and:
document.body).outerHeight(true) + 5 + ie}, 600

dklbwf
03-22-2013, 03:41 PM
Hey John, Thanks so much for quick response I tried that change and no luck still same results. i also changed the height from 300 to 100% but that made the box even smaller. Your solution is exactly what I need just need it to do no scrolling and just automatically fit in height...I've attached image of exact site that has the iframe and width is perfect but still getting scrollbar even with scrolling="no"
4997

THanks again!
Try Arie's 2 tweaks to it from post #9 in this thread:

http://www.dynamicdrive.com/forums/showthread.php?72554-jQuery-get-height-of-iframes-source&p=289091#post289091

jscheuer1
03-22-2013, 08:32 PM
There's nothing I can really do without a link to the page. Even then, some pages in the iframe cannot be easily read for height in some browsers, as I noted earlier in this thread:


And something else to be aware of (just as with any iframe resizing scheme) is that only works if the content that determines the height required by the window showing the page being loaded into the iframe is in the normal flow (position static or relative without going beyond the bottom) of the page. Absolute, relative, fixed, or floated content might cause problems, as can tables in some browsers.

You can choose trying to determine if there's anything like that on the remote page and/or look for things that have an offsetTop + offsetHeight that's greater than the document.body.offsetHeight (or the jQuery equivalents). But generally it's best not to use any of that stuff on the remote page.

dklbwf
03-25-2013, 08:19 PM
Below is the actual code that is contained in iframe page:


<cfset applicationName = "System Info Banner">
<cfquery name="qrySystemStatus" datasource="EnterpriseWebApplications-ReadOnly">
SELECT apps.DisplayName
FROM WAFApplication a
INNER JOIN WAFApplicationStatus apps
ON apps.ID = a.ApplicationStatusID
WHERE a.DisplayName = '#applicationName#'
</cfquery>

<cfquery name="qrySystemVariables" datasource="EnterpriseWebApplications-ReadOnly">
SELECT apps.DisplayName, apps.Value VarValue
FROM WAFApplication a
INNER JOIN WAFApplicationSettings apps
ON apps.ApplicationID = a.ID
WHERE a.DisplayName = '#applicationName#'
AND apps.Active = 1
AND apps.IsLeafEntry = 1
</cfquery>
<!--- Pull system variables and dynamically create and assign them --->
<cfloop query="qrySystemVariables">
<cfset "#DisplayName#" = "#VarValue#">
</cfloop>
<!---
Available variables are:
ShowBorder
ScrollSpeed_Vertical
ScrollSpeed_Horizontal
ScrollSpeed_Static
FontSize_Vertical
FontSize_Horizontal
FontSize_Static
--->

<cfif qrySystemStatus.DisplayName eq "Active">
<cfquery name="getRows" datasource="EnterpriseWebApplications-ReadOnly">
SELECT e.DisplayText,
dt.DisplayName DisplayType
FROM SIBEntry e
INNER JOIN SIBDisplayType dt
ON dt.ID = e.DisplayTypeID
WHERE e.Active = 1
AND GETDATE() BETWEEN e.FromDtm AND e.ToDtm
ORDER BY e.FromDtm, e.ToDtm, e.ID
</cfquery>

<cfif getRows.RecordCount neq 0>
<table border=<cfoutput>#ShowBorder#</cfoutput>>
<tr><td><b>System Info Banner</b></td></tr>

<cfquery dbtype="query" name="VerticalScrollingEntries">
SELECT * FROM getRows WHERE DisplayType = 'Scrolling-Vertical'
</cfquery>
<cfquery dbtype="query" name="HorizontalScrollingEntries">
SELECT * FROM getRows WHERE DisplayType = 'Scrolling-Horizontal'
</cfquery>
<cfquery dbtype="query" name="StaticEntries">
SELECT * FROM getRows WHERE DisplayType = 'Static'
</cfquery>

<tr><td>

<cfif VerticalScrollingEntries.RecordCount neq 0>
<marquee behavior="scroll" direction="up" scrollamount="<cfoutput>#ScrollSpeed_Vertical#</cfoutput>">
<font size="<cfoutput>#FontSize_Vertical#</cfoutput>"><b>
<cfoutput query="VerticalScrollingEntries">
**
#VerticalScrollingEntries.DisplayText#
**
<br><br>
</cfoutput>
</b></font>
</marquee>
</cfif>

<cfif HorizontalScrollingEntries.RecordCount neq 0>
<marquee behavior="scroll" direction="left" scrollamount="<cfoutput>#ScrollSpeed_Horizontal#</cfoutput>"><b>
<font size="<cfoutput>#FontSize_Horizontal#</cfoutput>"><b>
<cfoutput query="HorizontalScrollingEntries">
**
#HorizontalScrollingEntries.DisplayText#
**
</cfoutput>
</b></font>
</marquee>
</cfif>

<cfif StaticEntries.RecordCount neq 0>
<font size="<cfoutput>#FontSize_Static#</cfoutput>"><b>
<cfoutput query="StaticEntries">
<CENTER>#StaticEntries.DisplayText#</center>
<br>
</cfoutput>
</b></font>
</cfif>

</td></tr></table>
</cfif>
</cfif> Not sure what script or function may need to be added to this script to push the height to the other page that is calling this page from iframe...Thans again for your help/advice
There's nothing I can really do without a link to the page. Even then, some pages in the iframe cannot be easily read for height in some browsers, as I noted earlier in this thread:

jscheuer1
03-25-2013, 08:45 PM
I don't think you mentioned before that you were using Cold Fusion, are you? Those tags look like Cold Fusion tags. In any case they're not standard HTML tags, so presumably are replaced by valid HTML when served live.

And, that's what I would need to see, the live pages. Do you have it up anywhere you could post a link to it?

But, just from looking at that, it appears that the majority of the content is in a table. As I say, that can throw off some browsers. Try losing the table. Or, if that's impossible, once I see the live pages, I may be able to suggest something else.

It also looks as though that table is meant to be able to be scrolled. If so, absolute positioning might enter into it, that or a container div with overflow characteristics that might be throwing things off.

You could try using a normal page, rather than a CF one. That might fix it, if so, there's something about the CF page that's throwing things off.

One other thing you could try is putting a div around the table, perhaps even setting that div's height in css style.

For any specific help I would need to see it live. Put up a demo somewhere if you haven't already put this online. Either way, give us a link to it so we check it out.

dklbwf
03-26-2013, 06:40 AM
I apologize, yes the main code/page is built in ColdFusion which I dont have much experience with at all. I was just put in lead of getting the current Coldfusion System Banner embedded into our new site. The site is 100% internal site only viewable on our network which is no help at all i know:(. I have tried so many different things from different topics but nothing has worked yet, you are correct that the page does push out the data into table format. Users have 3 options when inserting a message, it can be static, horizontal scroll or vertical scroll and from there, their message is pushed out using the table format. I tried the div but no luck, i tried setting height to 100% but that didnt help. Any other ideas or am I totally out of luck with this situation? Our environment is 90% Internet Explorer 7 so IE is my main concern.

THanks so much again for your help