i looked for a javascript script that will change the height of an iframe, according to the loaded page in it, i found a code but it works for me only in IE and FireFox.. what should i change?
<SCRIPT type="text/javascript" LANGUAGE="javascript">
function reSize()
{
try{
var oBody = ifrm.document.body;
var oFrame = document.getElementById("ifrm");
oFrame.style.height = oBody.scrollHeight + (oBody.offsetHeight - oBody.clientHeight);
}
//An error is raised if the IFrame domain != its container's domain
catch(e)
{
window.status = 'Error: ' + e.number + '; ' + e.description;
}
}
</SCRIPT>
the iframe code:
<iframe width=940px onload=reSize() src="html/guides.html" id="ifrm" name="iframe_main" frameborder="0"></iframe>
thanks for helping!
For starters:
document.all has been obsolete for quite some time.
You should use getElementById.
Also if the iframe is not in your domain (e.g. you're in www.mydomain.com and the iframe loads content from www.someotherdomain.com) you WON'T be able to get the iframe's document.body with the normal security settings of most modern browsers... See here for details
Try var oBody = ifrm.contentDocument.body || ifrm.contentWindow.document.body;
Give an id to your iframe. I gave "myIframe" and after that use this line in your function instead of yours. it'll work everywhere:
document.getElementById("myIframe").setAttribute("height",600);
Related
I was looking for a solution for auto height adjusting depending on the contents that are inside the iframe, and this seems like it's working on chrome.
But for some reason, if i wait for the site to completely load, and then click on the 'Wall' tab on the main page, the iframe contents are not visible, as the height is set for '4px'.
Again, if you click on the wall tab while it's loading, or before it gets load, it works perfectly fine.
I'm guessing it has to do with the source.
The site I'm having problem with is here : http://xefrontier.com/
could anyone tell me why this phenomenon is happening?
and this is the source:
function resizeIframe(obj){
obj.style.height = 0;
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
}
function getDocHeight(doc) {
doc = doc || document;
// stackoverflow.com/questions/1145850/
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 iframe_board = document.getElementById(id);
var doc = iframe_board.contentDocument? iframe_board.contentDocument:
iframe_board.contentWindow.document;
iframe_board.style.visibility = 'hidden';
iframe_board.style.height = "10px"; // reset to minimal height ...
// IE opt. for bing/msn needs a bit added or scrollbar appears
iframe_board.style.height = getDocHeight( doc ) + 4 + "px";
iframe_board.style.visibility = 'visible';
}
document.getElementById('iframe_board').onload = function() { // Adjust the Id accordingly
setIframeHeight(this.id);
}
Solution for OP's issue is as follows:
A function that interacts with iframes works in Chrome but not in Firefox.
STOP If there is ever a problem with Firefox and Chrome is ok with interacting with iframes, then consider if this occurs in a PC, Mac, or both.
Chances are it's going to be Mac and it's wonderful relationship with Firefox (note: sarcasm cannot not be expressed very well on keyboard).
If the problem is isolated to the Mac running Firefox, then you can do the following to fix it 88.4% of the time.
Locate any event handlers that are listening for the load event on iframes:
ex. <iframe src="domain.com" onload="eventHandler()"></iframe>
REMOVE=================^-------===THIS===------^.
Disable/remove them.
At the very end of your </script> block add this:
ex. window.onload = eventHandler;
NOTE ===================^=^ -DO NOT ADD () at the end of function
Firefox Mac has many different issues unique onto itself, some by design. One of those bugs is it's inability to acknowledge an iframe's existence after it's been loaded. Firefox Mac will deal with iframes after everything else has been loaded. This is just my observation from experience.
use the following code to resize iframe height
<script language="javascript" type="text/javascript">
function resizeIframe(obj) {
obj.style.height = (obj.contentWindow.document.body.scrollHeight) + 'px';
}
</script>
and in iframe tag
<iframe src="somepage.php" width="100%" frameborder="0" scrolling="no" onload="resizeIframe(this)"></iframe>
Is there any way to resize a cross domain iframe according to its content, that would work in Firefox 3.6.10?
I thought that the postMessage command works, but a solution I found works in Firefox 12 but not in Firefox 3.6.10. Or maybe that's not the problem.
As I wrote in another question, youtube seems to be just embedding the content of the iframe in the page for the comment section, that's how it gets resized dynamically. And this would basically solve every iframe issue too, since the HTML would be embedded in the website's local HTML, and no same origin policy would block anything. When I asked about this, I didn't get answers though.
So thank you in advance, or if you don't like when people say that, I would be grateful if someone would helped.
And I CAN control the content inside the frame too!
(I need this for a script that makes youtube look like around 2012, so more people could be grateful too.)
You might try looking at this on GitHub.
https://github.com/davidjbradshaw/iframe-resizer
solution i found/modified:
in the page which contains the iframe:
<script type="text/javascript">
function resizeCrossDomainIframe(id, other_domain) {
var iframe = document.getElementById(id);
window.addEventListener('message', function(event) {
if (event.origin !== other_domain) return;
if (isNaN(event.data)) return;
var height = parseInt(event.data) + 32;
iframe.height = height + "px";
}, false);
}
in the iframe code:
<iframe id="my_iframe" onload="resizeCrossDomainIframe('my_iframe', '**whatever domain your iframe content is on**');"></iframe>
for continuous resizing, i put this in the page containing the iframe:
<script>
var interval = setInterval(function(){
resizeCrossDomainIframe('my_iframe', '**whatever domain your iframe content is on**');
}, 100);
</script>
on the iframe content page:
<script>
window.onload = function() {
window.parent.postMessage(document.body.scrollHeight, '**whatever domain your iframe containing page is on**');
}
</script>
and this for continuous resizing:
<script>
var interval2 = setInterval(function(){
window.parent.postMessage(document.body.scrollHeight, '**whatever domain your iframe containing page is on**');
}, 100);
</script>
CORRECTION: the first interval script isnt needed, since the eventlistener executes the function every time a message is sent to it. it would just cause slowness
This is my code
<script>
var body = "dddddd"
var script = "<script>window.print();</scr'+'ipt>";
var newWin = $("#printf")[0].contentWindow.document;
newWin.open();
newWin.close();
$("body",newWin).append(body+script);
</script>
<iframe id="printf"></iframe>
This works but it prints the parent page, how do I get it to print just the iframe?
I would not expect that to work
try instead
window.frames["printf"].focus();
window.frames["printf"].print();
and use
<iframe id="printf" name="printf"></iframe>
Alternatively try good old
var newWin = window.frames["printf"];
newWin.document.write('<body onload="window.print()">dddd</body>');
newWin.document.close();
if jQuery cannot hack it
Live Demo
document.getElementById("printf").contentWindow.print();
Same origin policy applies.
Easy way (tested on ie7+, firefox, Chrome,safari ) would be this
//id is the id of the iframe
function printFrame(id) {
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
return false;
}
an alternate option, which may or may not be suitable, but cleaner if it is:
If you always want to just print the iframe from the page, you can have a separate "#media print{}" stylesheet that hides everything besides the iframe. Then you can just print the page normally.
You can use this command:
document.getElementById('iframeid').contentWindow.print();
This command basically is the same as window.print(), but as the window we would like to print is in the iframe, we first need to obtain an instance of that window as a javascript object.
So, in reference to that iframe, we first obtain the iframe by using it's id, and then it's contentWindow returns a window(DOM) object. So, we are able to directly use the window.print() function on this object.
I had issues with all of the above solutions in IE8, have found a decent workaround that is tested in IE 8+9, Chrome, Safari and Firefox. For my situation i needed to print a report that was generated dynamically:
// create content of iframe
var content = '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">'+
'<head><link href="/css/print.css" media="all" rel="stylesheet" type="text/css"></head>'+
'<body>(rest of body content)'+
'<script type="text/javascript">function printPage() { window.focus(); window.print();return; }</script>'+
'</body></html>';
Note the printPage() javascript method before the body close tag.
Next create the iframe and append it to the parent body so its contentWindow is available:
var newIframe = document.createElement('iframe');
newIframe.width = '0';
newIframe.height = '0';
newIframe.src = 'about:blank';
document.body.appendChild(newIframe);
Next set the content:
newIframe.contentWindow.contents = content;
newIframe.src = 'javascript:window["contents"]';
Here we are setting the dynamic content variable to the iframe's window object then invoking it via the javascript: scheme.
Finally to print; focus the iframe and call the javascript printPage() function within the iframe content:
newIframe.focus();
setTimeout(function() {
newIframe.contentWindow.printPage();
}, 200);
return;
The setTimeout is not necessarily needed, however if you're loading large amounts of content i found Chrome occasionally failed to print without it so this step is recommended. The alternative is to wrap 'newIframe.contentWindow.printPage();' in a try catch and place the setTimeout wrapped version in the catch block.
Hope this helps someone as i spent a lot of time finding a solution that worked well across multiple browsers. Thanks to SpareCycles.
EDIT:
Instead of using setTimeout to call the printPage function use the following:
newIframe.onload = function() {
newIframe.contentWindow.printPage();
}
At this time, there is no need for the script tag inside the iframe. This works for me (tested in Chrome, Firefox, IE11 and node-webkit 0.12):
<script>
window.onload = function() {
var body = 'dddddd';
var newWin = document.getElementById('printf').contentWindow;
newWin.document.write(body);
newWin.document.close(); //important!
newWin.focus(); //IE fix
newWin.print();
}
</script>
<iframe id="printf"></iframe>
Thanks to all answers, save my day.
If you are setting the contents of IFrame using javascript document.write() then you must close the document by newWin.document.close(); otherwise the following code will not work and print will print the contents of whole page instead of only the IFrame contents.
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
I was stuck trying to implement this in typescript, all of the above would not work. I had to first cast the element in order for typescript to have access to the contentWindow.
let iframe = document.getElementById('frameId') as HTMLIFrameElement;
iframe.contentWindow.print();
Use this code for IE9 and above:
window.frames["printf"].focus();
window.frames["printf"].print();
For IE8:
window.frames[0].focus();
window.frames[0].print();
I am wondering what's your purpose of doing the iframe print.
I met a similar problem a moment ago: use chrome's print preview to generate a PDF file of a iframe.
Finally I solved my problem with a trick:
$('#print').click(function() {
$('#noniframe').hide(); // hide other elements
window.print(); // now, only the iframe left
$('#noniframe').show(); // show other elements again.
});
How do I clear the content of my IFRAME element, using javascript, without loading a blank page into it?
I can figure out to do this: iframe_element.src = "blank.html", but there must be a better, instant, method.
about:blank
is a "URL" that is blank. It's always clear
You can set the page's source to that, and it will clear.
var iframe = document.getElementById("myiframe");
var html = "";
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(html);
iframe.contentWindow.document.close();
tested in IE, Firefox and Chrome ... it did it :)
Your technique is the most robust. Its the one I use myself. At times content may be delivered over HTTPS and the use of about:blank can cause warning messages to appear to the effect of "do you want to include content from unsecure location" or some such thing.
Something being instant is a matter of perception however if you have a single Blank.html file on your site configured with a long cache expiry the client will only ever fetch the page once (at the most once per-session).
Or you can do this :
var iframe_element = window.frames['iframe_name'];
iframe_element.document.open();
iframe_element.document.close();
I have had difficulties with "about:blank" on pages with many IFrames. It does not seem to be a valid location in every browser (I never found out for sure, though). Anyway, I am happy with javascript:void(0);
You could also do this:
<html>
<head>
<script>
var doc = null;
window.onload = function() {
alert("Filling IFrame");
doc = document.getElementById("test");
if( doc.document ) {
document.test.document.body.innerHTML = "<h1>test</h1>"; //Chrome, IE
}else {
doc.contentDocument.body.innerHTML = "<h1>test</h1>"; //FireFox
}
setTimeout(function() {
alert("Clearing IFrame");
if( doc.document ) {
document.test.document.body.innerHTML = ""; //Chrome, IE
}else {
doc.contentDocument.body.innerHTML = ""; //FireFox
}
}, 1000);
};
</script>
</head>
<body>
<iframe id="test" name="test">
</iframe>
</body>
</html>
// First I get the window from its Id.
var my_content = document.getElementById('my_iframe').contentWindow.document;
// Then I clear it by setting the body tag inner HTML to an empty string.
my_content.body.innerHTML="";
// Now when I write my new content it does not get appended to the end of the body and the iframe body will contain only fresh content.
my_content.write(new_content);
Just do it:
var iframe = document.getElementById("iframe");
iframe.removeAttribute('srcdoc');
Work in Chrome
Just get the Iframe and remove the documentElement from it. The Iframe will be blank
var frame = document.getElementById("YourFrameId"),
frameDoc = frame.contentDocument || frame.contentWindow.document;
frameDoc.removeChild(frameDoc.documentElement);
function getContentFromIframe(iFrameName)
{
var myIFrame = document.getElementById(iFrameName);
var content = myIFrame.contentWindow.document.body.innerHTML;
//Do whatever you need with the content
}
$("#iframe").contents().find("body").html('');
Can someone please help me out with printing the contents of an IFrame via a javascript call in Safari/Chrome.
This works in firefox:
$('#' + id)[0].focus();
$('#' + id)[0].contentWindow.print();
this works in IE:
window.frames[id].focus();
window.frames[id].print();
But I can't get anything to work in Safari/Chrome.
Thanks
Andrew
Here is my complete, cross browser solution:
In the iframe page:
function printPage() { print(); }
In the main page
function printIframe(id)
{
var iframe = document.frames
? document.frames[id]
: document.getElementById(id);
var ifWin = iframe.contentWindow || iframe;
iframe.focus();
ifWin.printPage();
return false;
}
Update: Many people seem to be having problems with this in versions of IE released since I had this problem. I do not have the time to re-investigate this right now, but, if you are stuck I suggest you read all the comments in this entire thread!
Put a print function in the iframe and call it from the parent.
iframe:
function printMe() {
window.print()
}
parent:
document.frame1.printMe()
I used Andrew's script but added a piece before the printPage() function is called. The iframe needs focus, otherwise it will still print the parent frame in IE.
function printIframe(id)
{
var iframe = document.frames ? document.frames[id] : document.getElementById(id);
var ifWin = iframe.contentWindow || iframe;
iframe.focus();
ifWin.printPage();
return false;
}
Don't thank me though, it was Andrew who wrote this. I just made a tweak =P
In addition to Andrew's and Max's solutions, using iframe.focus() resulted in printing parent frame instead of printing only child iframe in IE8. Changing that line fixed it:
function printIframe(id)
{
var iframe = document.frames ? document.frames[id] : document.getElementById(id);
var ifWin = iframe.contentWindow || iframe;
ifWin.focus();
ifWin.printPage();
return false;
}
I had to make few modifications in order to make it with in IE8 (didn't test with other IE flavours)
1) document.frames[param] seem to accept a number, not ID
printIframe(0, 'print');
function printIframe(num, id)
{
var iframe = document.frames ? document.frames[num] : document.getElementById(id);
var ifWin = iframe.contentWindow || iframe;
ifWin.focus();
ifWin.printPage();
return false;
}
2) I had a print dialog displayed upon page load and also there was a link to "Click here to start printing" (if it didn't start automatically). In order to get it work I had to add focus() call
<script type="text/javascript">
$(function(){
printPage();
});
function printPage()
{
focus();
print();
}
</script>
Use firefox window.frames but also add the name property because that uses the iframe in firefox
IE:
window.frames[id]
Firefox:
window.frames[name]
<img src="print.gif" onClick="javascript: window.frames['factura'].focus(); parent['factura'].print();">
<iframe src="factura.html" width="100%" height="400" id="factura" name="factura"></iframe>
One thing to note is if you are testing this locally using file:///, it will not work on chrome as the function in the iframe will appear as undefined. However once on a web server it will work.
You can use
parent.frames['id'].print();
Work at Chrome!
You can also use
top.iframeName.print();
or
parent.iframeName.print();
The 'framePartsList.contentWindow.print();' was not working in IE 11 ver11.0.43
Therefore I have used
framePartsList.contentWindow.document.execCommand('print', false, null);
In Chrome:
Press Ctrl+Shift+C to select the iframe.
Click anywhere in the iframe.
Go to the console tab and type window.print();
This works because in Chrome Dev Tools, the window element adjusts to whatever <html> context you are in.
Use this:
window.onload = setTimeout("window.print()", 1000);