4

I'm trying to get an event for when a contentWindow.print() is finished (from an iframe).

I've seen this answer and it's given me a lot of hints on how to do this but none of the answers work for an iframe contentWindow.

So here's the setup I have so far:

const delay = (milliseconds) =>
  new Promise(resolve => setTimeout(resolve, milliseconds));

async function print(docUrl) {
  const iframe = document.createElement('iframe');
  document.body.appendChild(iframe);
  iframe.classList.add('hidden-iframe');

  console.log(docUrl);

  try {
    await new Promise<void>((resolve, reject) => {
      iframe.src = docUrl;

      const id = setTimeout(() => {
        reject(new Error('iframe timeout'));
      }, 10 * 1000);

      iframe.addEventListener('load', () => {
        clearTimeout(id);
        resolve();
      });
    });

    // wait 1 second just in case
    await delay(1000);
    const { contentWindow } = iframe;
    if (!contentWindow) {
      throw new Error('Could not get content window');
    }

    contentWindow.print();

    // TODO:  none of these events fire
    // 
    contentWindow.addEventListener('afterprint', e =>
      console.log('afterprint', e),
    );

    contentWindow
      .matchMedia('print')
      .addListener(e => console.log('print media', e));
    // 

    // this delay is just for testing.
    await delay(10 * 1000);
  } finally {
    document.body.removeChild(iframe);
  }
}

Any ideas on how to get an event when the iframe print dialog closes?


For more context, the docUrl is a string to a PDF URL that's on our own domain. This only needs to work for Google Chrome.

Rico Kahler
  • 17,616
  • 11
  • 59
  • 85

0 Answers0