57

Is it possible to detect when a user is printing something from their browser?

To complicate matters, if we are presenting a user with a PDF document in a new window is it possible to detect the printing of that document ( assuming the user prints it from the browser window)?

The closest I've been able to find is if we implement custom print functionality (something like this) and track when that is invoked

I'm primarily interested in a solution that works for internet explorer (6 or later)

TygerKrash
  • 1,362
  • 2
  • 20
  • 38

4 Answers4

122

You can now detect a print request in IE 5+, Firefox 6+, Chrome 9+, and Safari 5+ using the following technique:

(function() {
    var beforePrint = function() {
        console.log('Functionality to run before printing.');
    };
    var afterPrint = function() {
        console.log('Functionality to run after printing');
    };

    if (window.matchMedia) {
        var mediaQueryList = window.matchMedia('print');
        mediaQueryList.addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            } else {
                afterPrint();
            }
        });
    }

    window.onbeforeprint = beforePrint;
    window.onafterprint = afterPrint;
}());

I go into more detail into what this is doing and what it can be used for at http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/.

TJ VanToll
  • 12,584
  • 4
  • 43
  • 45
  • 1
    You're awesome. I've been searching for `onbeforeprint` Chrome/Safari support for days. Should've known better than to leave the warming embrace of SO. – Pat Oct 30 '12 at 12:35
  • 2
    +1, very nice, I'm planning on plagiarising this answer very shortly. – Andy E Jan 15 '13 at 21:20
  • 8
    This no longer seems to work in Chrome 38 on Windows. `beforePrint` never fires. http://jsfiddle.net/o5oosa9o/ (Right click the Results iframe and choose "Print...") – Michael Oct 15 '14 at 13:47
  • 3
    And afterPrint now fires in Chrome as soon as the print preview has finished rendering – Marcel Burkhard Jan 08 '15 at 10:50
  • last two comments confirmed with Chrome 39.0 as well :-( – Andreas Covidiot Jan 11 '15 at 03:01
  • 2
    Sorry for bumping this but I was led here from my question (http://stackoverflow.com/questions/28620711/extjs-4-creating-a-callback-for-an-override-function-for-printing-panel-conten), what if I want to detect the actual pressing of the "Print" button and not just any print request that the user issued? – Razgriz Feb 20 '15 at 16:06
  • on a Windows Server 2008 R2 box: 1) IE 11 fires the after event, before the print dialogue even comes up, 2) on Chrome 41.0.2272.89 m the after even fires as soon as the user hits the print button. this means that when printing to a file, if there's a dialogue that requests the file name to print to, the after even fires before that, 3) Firefox 36.0.1 behaves the same as Chrome. this means that closing window when the event fires won't work properly – wintersylf Mar 22 '15 at 00:58
  • Does this detect printing a pdf from the browser, as described in the question? – BenjaminGolder Jun 02 '16 at 06:48
  • I was using this "if ('matchMedia' in window)" along with window.onbeforeprint, which was a year ago, just stopped to work few days ago after the browser update. This answer seems a lot more stable. – X-HuMan Jun 09 '16 at 14:22
  • Saved me a lot of time –  Jan 27 '17 at 15:38
  • It is not called *before* printing is requested, but before the rendering is executed. Therefore if you for example change `document.title` inside of `beforePrint()` function, *it is too late* to have such change included in the printing result. – Ωmega Oct 02 '17 at 00:23
  • the `onafterprint` event worth nothing if it fires when the user either click on the `cancel` or `print` button !!! – user12163165 Aug 31 '20 at 22:36
7

For Internet Exploder, there are the events window.onbeforeprint and window.onafterprint but they don't work with any other browser and as a result they are usually useless.

They seem to work exactly the same for some reason, both executing their event handlers before the printing window opens.

But in case you want it anyway despite these caveats, here's an example:

window.onbeforeprint = function() {
    alert("Printing shall commence!");
}
Teekin
  • 12,581
  • 15
  • 55
  • 67
5

For anyone reading this on 2020. The addListener function is mostly deprecated in favor of addEventListener except for Safari:

if (window.matchMedia) {
  const media = window.matchMedia("print");
  const myFunc = mediaQueryList => {
    if (mediaQueryList.matches) {
      doStuff();
    }
  };
  try {
    media.addEventListener("change", myFunc);
  } catch (error) {
    try {
    media.addListener(myFunc);
    } catch (error) {
      console.debug('Error', error)
    }
  }
}

Reference: This other S.O question

Carlos R.
  • 251
  • 3
  • 8
2

If it's only for tracking purposes, perhaps you could set a background url in CSS print media to a server page (.aspx, .php, etc) and then do something on the server?

This guy claims it works.

This is not as versitile as TJ's solution, but it may be less buggy (see TJs blog post for issues he found) when only tracking is needed.

Christopher
  • 10,409
  • 13
  • 73
  • 97
  • I think there were a few problems with my approach, such as print previews etc, but for less than critical logging, it worked OK for me. – Adam K Dean Mar 02 '13 at 18:39