How to Print an Iframe from JavaScript in Safari/Chrome

How do I print an IFrame from javascript in Safari/Chrome

Put a print function in the iframe and call it from the parent.

iframe:

function printMe() {
window.print()
}

parent:

document.frame1.printMe()

Print iframe content in Opera and Chrome

This is a known bug in Opera. In addition to the above ideas for workarounds, you may want to play with something like this:

    var clone=document.documentElement.cloneNode(true)
var win=window.open('about:blank');
win.document.replaceChild(clone, win.document.documentElement);
win.print();

I have not tested this but it should create a copy of the page in a popup window and print it, without having to load the content a second time from the server or loosing any DOM modifications you may want printed.

How to print the contents of an iFrame using Javascript on iPad?

Okay, first of all. I did not solve the problem. I created a work-around that actually fakes what I want to achieve.

Because the iPad / iPhone simple prints the parent page, I wrap the complete body in a new div, then append the iFrame and some stylesheets which make sure that the printed document only contains the iFrame:

function printUrl( url ) {
$newBody = "<div class='do_not_print_this'>"
+ $( 'body' ).html()
+ "</div>"
+ "<iframe style='border: none; 0; width: 100%; margin: 0; padding: 0;' src='" + url + "' class='printFrame'></iframe>"
+ "<style type='text/css' media='all'>.printFrame { position: absolute; top: -9999999px; left: -99999999px; }</style>"
+ "<style type='text/css' media='print'>.do_not_print_this { display: none; } .printFrame { top: 0; left: 0; }</style>";
$( 'body' ).html( $newBody );

$( '.printFrame' ).load( function() {
var w = ( this.contentWindow || this.contentDocument.defaultView );
w.focus();
w.print();
} );
}

Hiding the iframe for the browser in the normal view is done using absolute positioning, using display on none or visibility hidden introduced weird behavior in the final print.

Yes, it's ugly. However, this is currently the only option I can think of which works. If any of you come up with a better solution, please let me know.

Javascript Print iframe contents only

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

How to override standard browser print and print an iframe by default

It's not possible (using Javascript). There is some experimental support for user-initiated print events in modern browsers, but those are not cancelable ("simple events") so the entire page will still print even if you interject custom code to print the frame of interest.

Given this limitation, your best bet is probably to offer users a large button that fires your custom frame printing function (see printContentFrameOnly below, fire it without arguments) and hope that they'll use the button instead of ctrl-p.

If it would be possible, this would be the way to do it (based on this answer):

// listener is a function, optionally accepting an event and
// a function that prints the entire page
addPrintEventListener = function (listener) {

// IE 5.5+ support and HTML5 standard
if ("onbeforeprint" in window) {
window.addEventListener('beforeprint', listener);
}

// Chrome 9+, Firefox 6+, IE 10+, Opera 12.1+, Safari 5.1+
else if (window.matchMedia) {
var mqList = window.matchMedia("print");

mqList.addListener(function (mql) {
if (mql.matches) listener(); // no standard event anyway
});
}

// Your fallback method, only working for JS initiated printing
// (but the easiest case because there is no need to cancel)
else {
(function (oldPrint) {
window.print = function () {
listener(undefined, oldPrint);
}
})(window.print);
}
}

printContentFrameOnly = function (event) {
if (event) event.preventDefault(); // not going to work
window.frames['webcontent'].focus();
window.frames['webcontent'].print();
}

addPrintEventListener(printContentFrameOnly);

How do print specific content inside the iframe

You can print a cross-domain iframe page perfectly by nesting the cross domain iframe in a locally hosted iframe. A "proxy iframe".

This way the parent javascript can print the proxy iframe without issue since it's local, which will transitively print it's inner iframe originating from another domain.

This technique works and has been verified by myself.

In your container page, host the iframe like this

 <iframe id="printf" name="printf" class="A4" src="/SomeController/IFrameProxy?url=TARGETURL"></iframe>

The proxy iframe should look like something like this

        @model string
<html>
<head>
<title>IFrame Proxy</title>
<style>
html, body, iframe {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border-style: none;
}
</style>

</head>
<body>
<iframe src="@Model" seamless></iframe>
</body>
</html>

The javascript that prints the iframe (defined on container page) should look something like this:

        function printFrame() {
var frm = document.getElementById("printf").contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
}


Related Topics



Leave a reply



Submit