jquery get height of iframe content when loaded
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>
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';
}
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 );
I found the following to work on Chrome, Firefox and IE11:
$('iframe').load(function () {
$('iframe').height($('iframe').contents().height());
});
When the Iframes content is done loading the event will fire and it will set the IFrames height to that of its content. This will only work for pages within the same domain as that of the IFrame.
The code to do this without jQuery is trivial nowadays:
const frame = document.querySelector('iframe')
function syncHeight() {
this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)
To unhook the event:
frame.removeEventListener('load', syncHeight)
You don't need jquery inside the iframe to do this, but I use it cause the code is so much simpler...
Put this in the document inside your iframe.
$(document).ready(function() {
parent.set_size(this.body.offsetHeight + 5 + "px");
});
added five above to eliminate scrollbar on small windows, it's never perfect on size.
And this inside your parent document.
function set_size(ht)
{
$("#iframeId").css('height',ht);
}
simple one-liner starts with a default min-height and increases to contents size.
<iframe src="http://url.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>
this is the correct answer that worked for me
$(document).ready(function () {
function resizeIframe() {
if ($('iframe').contents().find('html').height() > 100) {
$('iframe').height(($('iframe').contents().find('html').height()) + 'px')
} else {
setTimeout(function (e) {
resizeIframe();
}, 50);
}
}
resizeIframe();
});
Accepted answer's $('iframe').load
will now produce a.indexOf is not a function
error. Can be updated to:
$('iframe').on('load', function() {
// ...
});
Few others similar to .load
deprecated since jQuery 1.8: "Uncaught TypeError: a.indexOf is not a function" error when opening new foundation project
This is my ES6 friendly no-jquery take
document.querySelector('iframe').addEventListener('load', function() {
const iframeBody = this.contentWindow.document.body;
const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight);
this.style.height = `${height}px`;
});
This's a jQuery free solution that can work with SPA inside the iframe
document.getElementById('iframe-id').addEventListener('load', function () {
let that = this;
setTimeout(function () {
that.style.height = that.contentWindow.document.body.offsetHeight + 'px';
}, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate
});
Here is my solution, using pure JS for finding the total height of iframe
content.
NOTE:
Call this function after the iframe is loaded.
The iframe content must be in the same domain as the host page.
function getIframeBodyTotalHeight() { var frm = document.getElementById("appframe"); var frm_body = frm.contentWindow.document.body; var body_height = parseInt(frm_body.offsetHeight); var body_margin_top = parseInt(window.getComputedStyle(frm_body).getPropertyValue('margin-top').replace("px","")); var body_margin_bottom = parseInt(window.getComputedStyle(frm_body).getPropertyValue('margin-bottom').replace("px","")); var body_padding_top = parseInt(window.getComputedStyle(frm_body).getPropertyValue('padding-top').replace("px", "")); var body_padding_bottom = parseInt(window.getComputedStyle(frm_body).getPropertyValue('padding-bottom').replace("px", "")); var result = body_height + body_margin_top + body_margin_bottom + body_padding_top + body_padding_bottom; return result; }
精彩评论