preface

Print, as a mature technology for browsing, can often be used to print part of the content of a page. We can see a brief introduction about it on MDN.

Print (

The print() method prints the contents of the current window. Calling the print() method produces a print preview box that lets the user set the print request. The simplest way to print is to call window.print() directly, although document.execcommand (‘print’) can do the same. By default, everything in the body of the page is printed.


        
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>printDemo</title>
</head>
<body>
  <input type="button" value="Print this page" onclick="printpage()" />
  <div>content</div>
  <script>
    function printpage() {
      window.print()
    }
  </script>
</body>
</html>Copy the code


Second, print style

Call print() directly to print web content, we will find that the pre-adjusted layout and style can not be implemented, so what can help us to improve the user experience of printing?

[1] Use print style sheets

Add media=”print” to <link> to indicate that this is the style sheet that the printer will use, so that it will be applied to the document by default when printing

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

[2] Use 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:

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

[3] Inline styles use the media attribute

<style type="text/ CSS "media="print">Copy the code

[4] Use @import in CSS to introduce print style sheets

@import url("/path/print.css") print;Copy the code

Print part of the specified area

[1] Method one

Add <! At the beginning of the HTML corresponding to the body content to be printed. — startPrint –> flag, end with <! –endprint–> identifier, intercepts the contents between the print identifier and replaces the contents of the body with the print() method.

<body>
  <input type="button" value="Print this page" onclick="printpage()" />

  <! --startprint-->
  <div id="printContent">Print the content</div>
  <! --endprint-->

  <script>
    function printpage() {
      let oldStr = window.document.body.innerHTML; // Get the body content
      let start = "<! --startprint-->"; // Start printing the identifier, 17 characters long
      let end = "<! --endprint-->"; // The printing is complete
      let newStr = oldStr.substr(oldStr.indexOf(start) + 17); // Intercepts the content after the start of printing the logo
      newStr = newStr.substring(0, newStr.indexOf(end)); // Intercepts the content between the start and end print labels
      window.document.body.innerHTML = newStr; // Assign the specified content to be printed to the body
      window.print(); // Calls the browser's print function to print the specified area
      window.document.body.innerHTML = oldStr; // Body is replaced with the original content
    }
  </script>
</body>Copy the code

[2] Method two

Wrap the content you want to print in a large div, replace the content of the body with the content of that div, and call the print print() method.

<body>
  
  <input type="button" value="Print this page" onclick="printpage()" />
  <div id="printContent">Print the content</div>

  <script>
    function printpage() {
      let newstr = document.getElementById("printContent").innerHTML;
      let oldstr = document.body.innerHTML;
      document.body.innerHTML = newstr;
      window.print();
      document.body.innerHTML = oldstr;
      return false;
    }
  </script>
</body>Copy the code

[3] Method three

There are two events that can listen to print events, onbeforePrint () and onAfterPrint (), respectively before and after the print event is triggered.

Detect print requests, providing a pre-print processing event onbeforePrint () to hide elements that do not need to be printed, and a post-print processing event onAfterPrint () to release hidden elements

    window.onbeforeprint = function(event) {
      // Hide elements that do not need to be printed
    };
    window.onafterprint = function(event) {
      // Let go of hidden elements
    };Copy the code

Enforce paging

[1] Page-break-before ()

value describe
auto The default value. Insert a page break before the element if necessary.
always Insert a page break before the element.
avoid Avoid inserting page breaks before elements.
left Enough page breaks before the element, up to a blank left page.
right Enough page breaks before the element, up to a blank right page.
inherit Specifies that the page-break-before attribute should be inherited from the parent element.
/* Always insert a page break */ before the h1 element
@media print {
    h1 {page-break-before: always;}
}Copy the code

【2】 Page-break-after ()

value describe
auto The default value. Insert a page break after the element if necessary.
always Insert a page break after the element.
avoid Avoid inserting page breaks after elements.
left Enough page breaks after the element, up to a blank left page.
right Enough page breaks after the element, up to a blank right page.
inherit Specifies that the page-break-after attribute should be inherited from the parent element.
/* Always insert page breaks */ after the.footer element
@media print {
    .footer {page-break-after: always;}
}Copy the code

[3] Page-break-inside (used to set whether to insert page breaks in specified elements)

value describe
auto The default. Insert page breaks inside elements if necessary.
avoid Avoid inserting page breaks inside elements.
inherit Specifies that the page-break-inside property should be inherited from the parent element.
/* Avoid inserting page breaks */ in 
 and < blockQuote > elements


@media print {
pre.blockquote {page-break-inside: avoid;}
}Copy the code

[4] Be careful

  1. You cannot use these three paging attributes for absolutely located elements.
  2. Use the paging attribute as little as possible, and avoid using the paging attribute in tables, floating elements, and block elements with borders.

Five, set the print layout (horizontal, vertical, margin)

 @media print {
    @page {
      Vertical / * * /
      size: portrait; 

      / * * / laterally
      size: landscape;

      /* Margin upper right lower left */
      margin: 1cm 2cm 1cm 2cm; }}Copy the code

Remove the default browser header footer

Header printing default header footer information, to show the page margin range, we can remove the page model page margin, so that the content does not extend to the edge of the page, and then set the body element margin to ensure that A4 paper printed out of the page with margins

@media print {
  @page {
    margin: 0;
  }
  body {
    margin: 1cm; }}Copy the code

Seven, printing method encapsulation

[1] Encapsulation: Create a print.js file under utils

export default function printHtml(html) {
  let style = getStyle();
  let container = getContainer(html);

  document.body.appendChild(style);
  document.body.appendChild(container);

  getLoadPromise(container).then((a)= > {
    window.print();
    document.body.removeChild(style);
    document.body.removeChild(container);
  });
}

// Set the print style
function getStyle() {
let styleContent = `#print-container { display: none; } @media print { body > :not(.print-container) { display: none; } html, body { display: block ! important; } #print-container { display: block; }} `;
  let style = document.createElement("style");
  style.innerHTML = styleContent;
  return style;
}

// Clear the printed content
function cleanPrint() {
  let div = document.getElementById('print-container')
  if(!!!!! div) {document.querySelector('body').removeChild(div)
  }
}

// Create a DOM and populate it with the content to be printed
function getContainer(html) {
  cleanPrint()
  let container = document.createElement("div");
  container.setAttribute("id"."print-container");
  container.innerHTML = html;
  return container;
}

// Call the print method after the image is fully loaded
function getLoadPromise(dom) {
  let imgs = dom.querySelectorAll("img");
  imgs = [].slice.call(imgs);

  if (imgs.length === 0) {
    return Promise.resolve();
  }

  let finishedCount = 0;
  return new Promise(resolve= > {
    function check() {
      finishedCount++;
      if (finishedCount === imgs.length) {
        resolve();
      }
    }
    imgs.forEach(img= > {
      img.addEventListener("load", check);
      img.addEventListener("error", check); })}); }Copy the code

[2] Usage: Introduce print file and pass in DOM elements to be printed

import printHtml from "@/utils/print.js"

export default {
  methods: {
    print() {
      let printData = '
       
prints the content
'
printHtml(printData) } }, }Copy the code

The article is updated every week. You can search “Front-end highlights” on wechat to read it in the first time, and reply to [Books] to get 200G video materials and 30 PDF books