skip to Main Content

Ultimately I’m trying out a technique for printing a specific div, but I’m bogging down on this part of the problem.

I have some code which is supposed to copy from a div to a new iframe:

var iframe = document.createElement('iframe');
var div = document.querySelector('div#sidebar');
var content = div.innerHTML;
iframe.srcdoc = `<!DOCTYPE html><html><head></head><body>${content}</body></html>`;

document.body.append(iframe);

iframe.contentWindow.print();

I’ve tried this in the developer tools on one of the SO pages (there was a div#sidebar I could try it with).

I notice that I need to add the iframe to the document to get this to work at all. Otherwise the .contentWindow property is null.

The code seems to work to some extent, but the iframe is empty, or so it seems. What ends up being printed is nothing.

What’s the trick in creating a new iframe with copoied contents?

2

Answers


  1. Chosen as BEST ANSWER

    OK, I have an answer. I should have known better, since I’ve just finished teaching on a similar subject.

    The code works, but it runs too early. I need to wait for the document to finish loading.

    Here is a working version:

    var iframe = document.createElement('iframe');
    var div = document.querySelector('div#sidebar');
    var content = div.innerHTML;
    iframe.srcdoc = `<!DOCTYPE html><html><head></head><body>${content}</body></html>`;
    
    document.body.append(iframe);
    
    //  wait for iframe to finish loading:
        iframe.onload = () => {
            iframe.contentWindow.print();
            iframe.contentWindow.addEventListener('afterprint', event => {
                iframe.remove();
            });
        };
    

  2. For your reference here’s the "modal" solution I referred to in comment. Altering the page title and restoring it after printing is optional and can easily be omitted. If omitted the modal declarations could possibly be included in an @media print CSS rule depending on page functionality but I haven’t pursued it.

    "use strict";
    
    document.querySelector("#buttonId").addEventListener("click", event=> {
      const printDiv = document.querySelector("#divId");
      const pageTitle = document.title;
      document.title = "Print of DIV";
      printDiv.classList.add("modal");
      print();
      printDiv.classList.remove("modal");
      document.title = pageTitle;
    });
    .modal {   /* assuming the modal element is NOT within a positioned element */
       position: absolute;
       min-width: 100%;
       min-height: calc(100% - 3px);
       background-color: white;
       break-after: avoid;
    
    }
    <div id="divId">Hello folks and world</div>
    
    <button type="button" id="buttonId">Print</button>
    
    
    <p> and some page content that shouldn't be printed</p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search