Print iFrame only when CSS is loaded completely

Viewed 80

I’m printing selected parts of pages by putting them in an empty iframe. Everthing is fine except the CSS. Sometimes it’s there, sometimes not, so I guess the print function is loaded in moste cases before the css is complete. Unforntunately I’m obviously not able to solver the problem. The basic code:

var pStyles = new String ("<link href='/css/print.css' rel='stylesheet' type='text/css' id='cssprint' />");
var pWrapIn = new String ("<main><article><section>");
var pWrapOut = new String ("</section></article></main>");

function printFrame(fId) {
    window.frames["printhelper"].document.body.innerHTML = pStyles + pWrapIn + document.getElementById(fId).innerHTML + pWrapOut;
    console.log(window.frames["printhelper"].document.body.innerHTML);
    window.frames["printhelper"].window.focus();
    window.frames["printhelper"].window.print();
}

This works, but with the described CSS issue. To make sure the CSS is loaded, I ended up with the modified function, which is not working at all:

function printFrame(fId) {
    window.frames["printhelper"].document.body.innerHTML = pStyles + pWrapIn + document.getElementById(fId).innerHTML + pWrapOut;
    console.log(window.frames["printhelper"].document.body.innerHTML);
    $(#cssprint).on('load', function() {
        console.log ('CSS loaded');
        window.frames["printhelper"].window.focus();
        window.frames["printhelper"].window.print();
    }, 0);
}

#cssprint seems to be loaded never, so console.log stays empty and no print is done. But what am I doing wrong? (The function printFrame is called by a simple onClick in the HTML markup.)

2 Answers

I would probably do something like this:

  • Add onload event handler to CSS link that calls a function that posts a message to the parent window (parent.postMessage(...)) or directly does so, then you do not need an extra script tag.
  • The outer window listens to the message of the iframe window and starts printing when receiving it.

You can also just skip the message posting if you do not need to synchronize anything with the parent window an just print directly in the onload event:

<link onload="window.print()" ...>

See MDN for more info on posting and receiving messages.

The complete working function (thanks to H. B.):

var pStyles = new String ("<link href='/css/print.css' rel='stylesheet' type='text/css' onload='window.focus(); window.print()' />");
var pWrapIn = new String ("<main><article><section>");
var pWrapOut = new String ("</section></article></main>");

function printFrame(fId) {
    window.frames["printhelper"].document.body.innerHTML = pStyles + pWrapIn + document.getElementById(fId).innerHTML + pWrapOut;
}
Related