Blog address jsonz1993. Making. IO / 2018/06 / win…

Github welcomes Start Follow

Recently there is a demand is to do page printing, take this opportunity to fill the relatively unpopular browser printing knowledge. This article deals only with Chrome, Safari, and Firefox.

Print interface

First of all, browser printing is a very mature application ~ at least it has been available for a long time, so there will be no compatibility issues

The simplest way to print is to call window.print() directly, although document.execcommand (‘print’) can do the same.

In Both Safari and Chrome, the print preview window pops up. FireFox doesn’t preview, but lets you choose a printer. OSx lets you preview a PDF

Generally, this method of calling print directly on the web page cannot meet our business requirements. For example:

  • Adjust layout and font size to fit A4 paper
  • Use different styles when printing
  • Print with a higher resolution image
  • Something unrelated doesn’t appear in the print, etc., etc

So what can we do to improve the user experience of printing?

Use print Style Sheet

We can add media=”print” to the link to indicate that this is the style sheet that the printer will apply, as in:

<link href="/example.css" media="print" rel="stylesheet" />
Copy the code

When printing, the style sheet will be applied to the document by default

Using media query

When there are not many styles to change, there is no need to write a new style sheet, just write a media query can achieve the same effect, such as:

h1 {
  font-size: 14px;
}
@media print {
  h1 {
    font-size: 20px; }}Copy the code

Event listeners

beforeprint && afterprint

There are two events that can listen to print events, beforePrint and AfterPrint, respectively before and after the print event is triggered. This event is already supported in IE6, but I’m not surprised at all. After all, IE has long supported many interface calls.

window.addEventListener('beforeprint', () = > {document.body.innerHTML = 'Printing... ';
});
window.addEventListener('afterprint', () = > {document.body.innerHTML = 'Print done... ';
});
Copy the code

Window.matchmedia tests the media query interface

If you want Safari compatibility, you might want to try Window. matchMedia compatibility with IE10+, which is fine with other major browsers.

The use of this is slightly different. First create a MediaQueryList object and listen for changes through it, as in:

const printMedia = window.matchMedia('print');
function printChange({ matches, }) {
  document.body.innerHTML = matches? 'Printing... ': 'Print done/cancel';
}
printMedia.addListener(printChange);
Copy the code

More customized print area/print content

If the project is using JQ, etc., or if you want to simply print an area without rewriting the stylesheet, etc. The dumbest way to do this is to use jQ plugin jquery.print

Create an iframe, throw in the DOM and style sheet that you want to print, and call the iframe print event. So here’s a simple demo

function printPartial(dom, { title= document.title,}= {}) {
  if(! dom)return;
  let copyDom = document.createElement('span');
  const styleDom = document.querySelectorAll('style, link, meta');
  const titleDom = document.createElement('title');
  titleDom.innerText = title;

  copyDom.appendChild(titleDom);
  Array.from(styleDom).forEach(item= > {
    copyDom.appendChild(item.cloneNode(true));
  });
  copyDom.appendChild(dom.cloneNode(true));

  const htmlTemp = copyDom.innerHTML;
  copyDom = null;

  const iframeDom = document.createElement('iframe');
  const attrObj = {
    height: 0.width: 0.border: 0.wmode: 'Opaque'
  };
  const styleObj = {
    position: 'absolute'.top: '-999px'.left: '-999px'};Object.entries(attrObj).forEach(([key, value]) = > iframeDom.setAttribute(key, value));
  Object.entries(styleObj).forEach(([key, value]) = > iframeDom.style[key] = value);
  document.body.insertBefore(iframeDom, document.body.children[0]);
  const iframeWin = iframeDom.contentWindow;
  const iframeDocs = iframeWin.document;
  iframeDocs.write(` 
      `);
  iframeDocs.write(htmlTemp);
  iframeWin.focus();
  iframeWin.print();
  document.body.removeChild(iframeDom);
}

printPartial(document.querySelector('#description'));
Copy the code

A few final things to note

  • Printing prints all visible elements under document, including<header>The inside of the
  • The background will not be printed, including the background color, background image and so on
  • If the image is loaded lazily, special treatment is required, otherwise it will be blank when printing

Reference:

Blog.csdn.net/fengshuiyue…

Mozilla print

Mozilla Using_a_print_style_sheet