1

I made a function to print innerHTML and its stylesheet of a div.

I'm having a little problem here though, because the div needs some external fontface files to load, the window.print() needs a small delay, in order to wait for the font files to load completely before it executes.

So I used setTimeout() in order to delay print() for a few seconds, but it doesn't seem to work, when the function is executed, the printing page of the browser still loads immediately. Is there any way to improve this code?

function printdiv() {
  var headstr = "<html><head><title>file_name</title></head><body>";
  var footstr = "</body></html>";
  var newstrstyle = document.getElementsByTagName("style")[0].innerHTML;
  var newstr = document.getElementById("divID").innerHTML;
  var oldstr = document.body.innerHTML;
  document.body.innerHTML =
    headstr + "<style>" + newstrstyle + "</style>" +"<div id='divID'>" + newstr + "</div>" + footstr;
  setTimeout(window.print(), 2000); // is this right?
  document.body.innerHTML = oldstr;
  return false;
}
Henry
  • 154
  • 10
  • 1
    `window.print()` should be `window.print`, without the parenthesis – clod9353 Jan 24 '21 at 17:47
  • @clod9353 if so, it seems to print the entire webpage, not only the `div`... – Henry Jan 24 '21 at 17:53
  • You won't be able to print only a section of the current page, only the entire webpage, take a look at the [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/print) – Guerric P Jan 24 '21 at 17:55
  • You would have to create a new document like in this answer: https://stackoverflow.com/questions/2255291/print-the-contents-of-a-div#answer-2255438 – Guerric P Jan 24 '21 at 17:56
  • @GuerricP https://stackoverflow.com/questions/2255291/print-the-contents-of-a-div this question is where I got the idea to recreate the div and only print the element. I checked your answer, but changing to `window.print` only prints the entire webpage, unlike the one with parenthesis. My code that I've written above works fine, except that it does not give time for fontface files to load. – Henry Jan 24 '21 at 18:01
  • Oh OK I read too fast sorry, you didn't implement the answer correctly. It's all about creating a **new** document with `window.open` – Guerric P Jan 24 '21 at 18:01
  • @GuerricP understood, thanks. – Henry Jan 24 '21 at 18:06

2 Answers2

0

By writing this:

setTimeout(window.print(), 2000);

You are passing the result of the window.print() function call into setTimeout which is not what you want.

You dont want to pass the function result but the function itself, then write this:

setTimeout(window.print, 2000);

Also, Window.print() won't let you choose which section of the page to print, so you need to create a new document that contains what you want to print:

function printdiv() {
    var newstrstyle = document.getElementsByTagName("style")[0].innerHTML;
    var newstr = document.getElementById("divID").innerHTML;

    var mywindow = window.open('', 'PRINT', 'height=400,width=600');

    mywindow.document.write('<html><head><title>' + document.title + '</title>');
    mywindow.document.write('</head><body >');
    mywindow.document.write('<h1>' + document.title + '</h1>');
    mywindow.document.write(`<style>${newstrstyle}</style><div id='divID'>${newstr}</div>`);
    mywindow.document.write('</body></html>');

    mywindow.document.close(); // necessary for IE >= 10
    mywindow.focus(); // necessary for IE >= 10*/

    setTimeout(() => {
        mywindow.print();
        mywindow.close();
    }, 2000);
    
}

Credit goes to this answer: Print the contents of a DIV

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • You've delayed `mywindow.print`, but not `mywindow.close`, so it is going to close the window before the print resolves. – Quentin Jan 24 '21 at 18:37
0

It will be better to do it when the document content is loaded.

document.addEventListener('DOMContentLoaded', function(event) {
    window.print();
});
Gal Gur-Arie
  • 376
  • 3
  • 6