Impression ciblée d'éléments avec window.print()

La méthode print() de l'objet window permet de déclencher l'impression du contenu de la page. Par défaut, elle imprime tous les éléments présents dans l'élément body. Il n'est pas posible de spécifier un élément particulier à imprimer directement. Cependant, il existe trois contextes où l'on peut accéder à un objet window en JavaScript :

  1. L'objet window de la page actuelle.
  2. L'objet window contenu dans un élément iframe.
  3. L'objet window généré par la méthode window.open().

1. Utilisation de l'objet window de la page actuelle

Pour imprimer un élément spécifique en utilisant l'objet window de la page coruante, il faut remplacer le contenu de l'élément body au moment de l'impression. Cette méthode est simple à mettre en œuvre.

  • Avantage : Facilité d'implémentation, il suffit de manipuler le body.
  • Inconvénient : Cette approche n'est pas adaptée aux applications modernes basées sur des frameworks comme Vue ou React. Dans ces cas, une partie du JavaScript et du CSS peut être intégrée au body, et un remplacement direct pourrait entraîner la perte de fonctionnalité de certains éléments ou de styles.

// Sauvegarde du contenu original du body
const contenuOriginal = window.document.body.innerHTML;
// Récupération du contenu de l'élément cible
const nouveauContenu = document.querySelector('.element-cible').innerHTML;
// Remplacement du contenu du body par le contenu cible
window.document.body.innerHTML = nouveauContenu;
// Déclenchement de l'impression
window.print();
// Restauration du contenu original du body
window.document.body.innerHTML = contenuOriginal;

2. Utilisation de l'objet window d'un élément iframe (Recommandé)

L'impression via un iframe est la méthode la plus fiable. Cependant, il faut tenir compte des restrictions de sécurité liées aux navigateurs. Il est crucial que l'iframe généré soit de même origine (same-origin) que la page actuelle pour pouvoir manipuler son contenu. Si ce n'est pas le cas, l'accès aux éléments internes sera bloqué.

  • Avantages :
    • Impression transparente pour l'utilisateur, sans mdoification visible sur la page principale.
    • Possibilité d'effectuer des personnalisations avancées.
  • Inconvénient : Nécessite de supprimer l'élément iframe créé après l'opération.

/**
 * Supprime l'iframe d'impression s'il existe.
 */
function supprimerIframeImpression() {
    const iframeExistant = document.querySelector('.iframe-impression-cible');
    if (iframeExistant) {
        iframeExistant.remove();
    }
}

/**
 * Déclenche l'impression d'un élément spécifique via un iframe.
 */
function imprimerElementCible() {
    supprimerIframeImpression(); // Nettoyage préalable

    // Sélection de l'élément à imprimer
    const elementAImprimer = document.querySelector('.element-cible');
    if (!elementAImprimer) {
        console.error("L'élément cible n'a pas été trouvé.");
        return;
    }

    // Création de l'élément iframe
    const iframeElement = document.createElement('iframe');
    iframeElement.className = 'iframe-impression-cible';
    // Positionnement discret pour ne pas interférer avec le contenu existant
    iframeElement.style.position = "fixed";
    iframeElement.style.top = "-9999px";
    iframeElement.style.left = "-9999px";
    iframeElement.style.width = "0";
    iframeElement.style.height = "0";
    iframeElement.style.border = "none";

    // Ajout de l'iframe au document
    document.body.appendChild(iframeElement);

    // Accès au document de l'iframe
    const docIframe = iframeElement.contentDocument;
    if (!docIframe) {
        console.error("Impossible d'accéder au document de l'iframe.");
        supprimerIframeImpression();
        return;
    }

    // Copie profonde de l'élément cible pour éviter de le déplacer de la page principale
    docIframe.body.appendChild(elementAImprimer.cloneNode(true));

    // Styles pour supprimer les marges et les en-têtes/pieds de page par défaut de l'impression
    const styleImpression = document.createElement('style');
    styleImpression.media = "print";
    styleImpression.innerText = `
        @page {
            size: auto;
            margin: 0mm;
        }
        body {
            margin: 0;
        }
    `;
    docIframe.head.appendChild(styleImpression);

    // Déclenchement de l'impression via la fenêtre de l'iframe
    iframeElement.contentWindow.print();

    // Optionnel: Supprimer l'iframe après un court délai pour laisser le temps à l'impression de démarrer
    // setTimeout(supprimerIframeImpression, 1000); // Délai de 1 seconde
}

3. Utilisation de l'objet window généré par window.open() (Non recommandé)

L'utilisation de window.open() pour imprimer est la moins recommandée. En effet, la fenêtre d'impression s'ouvre en tant que nouvelle fenêtre, et si celle-ci n'a pas la même taille que la fenêtre d'origine, cela peut créer une expérience utilisateur peu agréable visuellement.

  • Avantage : Comme avec l'iframe, cela crée un nouvel objet window, permettant des opérations personnalisées sans affecter la fenêtre principale.
  • Inconvénient : L'ouverture d'une fenêtre distincte n'est pas une opération discrète ("sans perception") et peut interrompre le flux de l'utilisateur.

// Ouvre une nouvelle fenêtre
const fenetreImpression = window.open('', 'fenetreImpression', 'width=600,height=400,resizable=yes');

if (fenetreImpression) {
    // Écrit le contenu de l'élément cible dans la nouvelle fenêtre
    fenetreImpression.document.write(`
        
        
            <title>Impression</title>
            <style>
                @page {
                    size: auto;
                    margin: 0mm;
                }
                body {
                    margin: 0;
                }
            </style>
        
        
            ${document.querySelector('.element-cible').innerHTML}
        
        
    `);
    fenetreImpression.document.close(); // Important pour que le contenu soit rendu

    // Déclenchement de l'impression dans la nouvelle fenêtre
    fenetreImpression.print();

    // Fermeture de la nouvelle fenêtre après un court délai (optionnel)
    // setTimeout(() => {
    //     fenetreImpression.close();
    // }, 2000);
} else {
    alert("L'ouverture de la fenêtre d'impression a été bloquée par le navigateur. Veuillez autoriser les pop-ups pour ce site.");
}

Étiquettes: JavaScript Impression web development window.print iframe

Publié le 22 juillet à 23h46