I have a specific problem with page printing in JavaScript. I need to open my page on another tab with all scripts removed (this way: $(document).get(0).documentElement.innerHTML.replace(/<script[^>]+>.*?<\/script>/gi, '')
and then call window.print()
inside new tab, and close it afterwards.
That's because errors in scripts are causing problems with printing. Code responsible for the whole printing:
var w = window.open();
w.document.write(
$(document).get(0).documentElement.innerHTML.replace(/<script[^>]+>.*?<\/script>/gi,'')
);
w.document.close();
var loadingImagesInterval = setInterval(function() {
var imgs = w.document.querySelectorAll('img');
for (var i = 0; i < imgs.length; i++) {
if (!imgs[i].complete) return;
}
clearInterval(loadingImagesInterval);
w.focus();
w.print();
w.close();
}, 100);
Basically, the problem is, on iOS, w.print()
seems not to block code execution until confirm/cancel in printing view and w.close()
is called immediately after. All other browsers work just fine: Mac Chrome, Mac Safari, IE11, Mac Firefox. All fine. Just not iOS Safari.
I tried this code, but didn't work as well:
w.matchMedia('print').addListener(function(mql) {
if (!mql.matches) {
w.close();
}
})
Is there a better way to deal with my problem?
EDIT: iOS version 12.2 introduced a "Done" button when opening a page from the Home Screen, so there is no need for a CLOSE button as described below. It is only needed for 12.0 and lower.
I worked around this by:
write()
because it opens a new page, and the close button will not return the user to the previous page.Caveat:
// detect Safari
if (navigator.userAgent.indexOf("Safari") !== -1) {
// make print button
const print_button = document.createElement('button');
const print_button_text = document.createTextNode("Print");
print_button.appendChild(print_button_text);
print_button.addEventListener(
"click",
function() {
// hide the buttons before printing
print_button.style.display = 'none';
close_button.style.display = 'none';
newWindow.print();
// delay reappearing of the buttons to prevent them from showing on the print
setTimeout(() => {
print_button.style.display = 'block';
close_button.style.display = 'block';
}, 2000);
},
false
);
// make close button
const close_button = document.createElement('button');
const close_button_text = document.createTextNode('Close');
close_button.appendChild(close_button_text);
close_button.addEventListener(
"click",
function() {
newWindow.close();
},
false
);
newWindow.document.body.appendChild(print_button);
newWindow.document.body.appendChild(close_button);
};
And then I added the content I wanted to print. I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With