Détecter un événement impression en javascript
Quant un utilisateur décide d’imprimer une page web, on a parfois besoin de la modifier dynamiquement en javascript. Il est possible de détecter cet événement, nous allons voir comment.
Avant toute chose, ce que nous allons décrire permet de se faire avec les navigateurs Microsoft Internet Explorer 5 et supérieur, Mozilla Firefox 6 et supérieur, Google Chrome 9 et supérieur ainsi Apple Safari 5 et supérieur.
Les événements window.onbeforeprint et window.onafterprint ne font partie d’aucune spécification. Les lignes suivantes fonctionnent avec IE 5 et supérieur, Firefox 6 et supérieur mais pas avec Webkit (donc pas safari) et Opéra.
window.onbeforeprint = function() { console.log("Appel fait avant l'impression"); }; window.onafterprint = function() { console.log("Appel fait après l'impression"); };
Concernant Webkit, l’anomalie est référencée sous l’identifiant 19937. Heureusement, depuis cette déclaration sur le bugzilla de Webkit, une fonctionnalité de ce type a été mis en place pour ce navigateur : window.matchMedia.
Cette fonctionnalité permet de déterminer si le document courant correspond à une requête média comme (exemple extrait de la documentation officielle de mozilla media query) :
if (window.matchMedia("(min-width: 400px)").matches) { /* the view port is at least 400 pixels wide */ } else { /* the view port is less than 400 pixels wide */ }
Avec un écouteur, il est possible de savoir si la fenêtre est redimenssionnée comme le montre le code suivant :
var mediaQueryList = window.matchMedia(' (min-width: 600px) '); mediaQueryList.addListener(function(mql) { if (mql.matches) { console.log('The viewport is at least 600 pixels wide'); } else { console.log('The viewport is less than 600 pixels wide'); } });
Un fait intéressant, c’est que ce comportement est le même lorsqu’un utilisateur lance une impression (https://code.google.com/p/chromium/issues/detail?id=105743).
var mediaQueryList = window.matchMedia('print'); mediaQueryList.addListener(function(mql) { if (mql.matches) { console.log('onbeforeprint equivalent'); } else { console.log('onafterprint equivalent'); } });
En combinant ces deux approches, on peut faire fonctionner la gestion de l’impression sous IE5+, FF6+, Chrome9+ et Safari 5.1 mais hélas pas sous Opéra.
(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; }());
Pour de plus amples informations sur ce sujet, je vous invite à lire l’article de TJ Van Toll écrit en anglais sous le titre Detecting Print Requests with JavaScript.
Bonjour,
pour répondre à la problématique de pouvoir préparer une version imprimable à l’aide de javascript, j’avais utilisé une tout autre méthode il y a quelques années maintenant. (méthode compatible tout navigateur depuis qu’il est possible d’utiliser des feuilles de style pour écran et des feuilles de style pour l’impression.
Le principe est simple :
une fois la page chargé (onload), je crée en arrière plan une copie intégrale de la page div identifié « print-version ». Cette version est en display:none pour le media screen et inversement, la version d’origine est en display:none pour le media print.
De cette façon on ne transfert aussi qu’une fois les données entre serveur et client et on est compatible tout navigateur.
Le principal inconvénient que je vois par rapport aux écouteurs d’évènement print décrit dans le poste, c’est l’impossibilité de traquer les impressions avec un outil d’analytique.
Bonjour,
en effet, votre solution est tout aussi intéressante. Merci de nous l’avoir communiqué.
Concernant l’appel d’un outil de tracking comme Google Analytics, ça ne doit pas être un point vraiment bloquant puisqu’on peut toujours créer dynamiquement une iframe contenant le js de l’outil de tracking.
Votre technique semble néanmoins plus pertinente que celle de Van Toll puisqu’elle doit pouvoir fonctionner sur tous les navigateurs.
Arnaud