Frederic Fortier
Frederic Fortier

Reputation: 750

Detect print events from iFrame

I am trying to build a print solution which programmatically prints PDF documents using URLs and fire an event after printing.

I am using the "matchMedia" event listener below to test with Chrome (v54). For IE and Firefox, I plan to listen to the "onbeforeprint" and "onafterprint" of the same iframe contentWindow object.

Here is how I invoke the print. The dojo function is just an xhr wrapper.

                dojoRequest(url, {
                    handleAs: 'blob'
                }).then(function (blob) {
                    var src = URL.createObjectURL(blob);

                    printFrame = document.createElement('iframe');
                    printFrame.id = 'print-frame';
                    // printFrame.style.display = 'none';
                    printFrame.src = src;
                    document.body.appendChild(printFrame);

                    var mediaQueryList = printFrame.contentWindow.matchMedia('print');
                    mediaQueryList.addListener(function (mql) {
                        console.log('print event', mql);
                        debugger;
                    });

                    setTimeout(function () {
                        printFrame.contentWindow.print();
                    }, 0);
                });

This works well except that the "print event" event never fires. I would expect it to fire once when showing the "print preview" window and again after clicking the "print" button.

I tried registering the same event listener against the main "window" object. It fires when initiating a print manually (from the File menu), but not when initiating the print programmatically using the method described above.

Upvotes: 0

Views: 6023

Answers (1)

ntahoang
ntahoang

Reputation: 451

To get events, you must wrap your code inside of onload of iframe, like this:

printFrame.onload = function () {
  var mediaQueryList = printFrame.contentWindow.matchMedia('print');
  mediaQueryList.addListener(function (mql) {
    console.log('print event', mql);
  });

  setTimeout(function () {
    printFrame.contentWindow.print();
  }, 0);
};

However, I still think that this approach is really complex and not stable enough for enterprise application.

UPDATE:

Jsfiddle link showing it works on Chrome 54: https://jsfiddle.net/anhhnt/nj851e52/

Upvotes: 3

Related Questions