0

I want to print a different content from my web page that includes an image. So is my JavaScript code:

function print() {
 var w = window.open();  
 w.document.write(....);  
    //  time for rendering images
 setTimeout(function () { w.print();  w.close();},10);
}

Google Chrome shows a new tab, with no print dialog. When I exit the tab and return it, the print dialog shows!

When I take out the 10 ms timeout, it not shows my image (there is no time for rendering the image), but the dialog shows instantly.

Maybe, someone will tell me: Creates HTML using DOM functions like createElement and appendChild. So you don't need rendering time and it is neater.

Therefore I did an alternative with whole HTML content created from scratch

I've used the src dinamic assigment for my image

ele.setAttribute("src","LogoUp.png"); // ele is an image element

instead using a static HTML with same src value

<img id="header" style="margin-left: auto;
    margin-right:auto;" src="LogoUp.png" >

PS: My Chrome is updated (v.63)

Now there is no need for rendering time and I can extract the setTimeout function call, however the image is not loading. It's very weird. I saw it in the Chrome DevTools, the official Chrome debugger tool. It shows a right string, but no image is pointed.

I'm using a local computer with Windows 7 and the image is in the same directory as the html source.

So I'm crazy ...

Update:
I also have tried, with no success: (I also saw the html in Chrome DevTools )

 c.appendChild(document.getElementById("header").cloneNode(true))
// where c is the image's parent element 

It's amazing because the original image works, when using innerHTML

Paulo Buchsbaum
  • 2,471
  • 26
  • 29

1 Answers1

0

I've made more research and I've discovered a great solution without the need for a popup tab. The magic was made by iFrame. An empty one:

<iframe id="luck" style="border:none;" >
</iframe>

In other point, I've placed the content to be printed (with images)

<div class="printer" style="margin:0; padding:0; display:none"> 
...
</div>

Display is set with "none" (since I don't want to display that content on the page).

The print code is below in just 2 lines (long ones):

function procPrint() {
  document.getElementById("luck").contentDocument.body.innerHTML =    
    document.getElementsByClassName('printer')[0].innerHTML;
  setTimeout(function() {luck.contentWindow.print();},10); 
   // just 10 ms waiting time is enough, 
   //  maybe complex content demands more.
} 

Advantages:

  • No popup. Cancel or OK resumes the original page.
  • Print dialog is not missing. No tab to be changed.

Disadvantages:

  • Rendering of innerHTML assignment demands setTimeout use.
  • Firefox does not give an error, but the printing does not work. My goal is just a prototype. So for me, I'm ok.

-/-

I did not testing the src bug (correct string don't display the image) with DOM assignments.

I'm satisfied with what I got. I hope it will be useful for someone.

Update:

I've discovered that iFrame printing ignores completely CSS resources like a printing CSS file:

<link rel="stylesheet" type="text/css" href="/print.css" media="print" />

or @media print specs inside a CSS file like:

@media print {
   body { font-size: 14pt }
}

It occurs because logically the frame is another document. So the style needs to be attached in the HTML that will be cloned inside iFrame or it's possible includes css file dinamically in the child after cloning HTML inside the iFrame (see here).

My brain understand the logic, but it's weird: If you puts a style in the HTML printing source it works, but if you use the class name in the CSS file, it changes the clone source but not in the cloned nodes.

If one needs to change or set the background color (or image) in the printing, changes directly in the body iframe. One specifies background color in the cointaner doesn't make the work.

In this case, add the below line in procPrint function above.

d.style.backgroundColor  = "#FF0000";  

Update 2 For invisible iFrame on the screen uses:

@media screen{    
    .printonly, .printonly *  {
        display: none !important;
    }
}
Paulo Buchsbaum
  • 2,471
  • 26
  • 29