Fenêtre Javascript.imprimer () dans chrome, fermer une nouvelle fenêtre ou un nouvel onglet au lieu d'annuler l'impression laisse javascript bloqué dans la fenêtre mère

dans l'application sur laquelle je travaille, nous avons plusieurs endroits différents où un utilisateur peut imprimer. Dans tous ces cas, nous utilisons le même workflow d'ouverture d'une nouvelle fenêtre(ou onglet), en écrivant tout ce que nous avons besoin d'imprimer sur le document de la nouvelle fenêtre, puis nous appelons

    $(w.document).ready(function () {
        w.focus();
        w.print();
        w.close();
    });  

le problème que je vois est que dans Chrome, si je ferme l'onglet ou la fenêtre qui est ouverte pour l'aperçu d'impression au lieu de cliquer sur le bouton Annuler, Chrome bloque toujours le javascript sur la fenêtre de mes parents.

C'est comme pour le problème décrit ici:

Google Chrome bloque les requêtes ajax lorsque l'aperçu d'impression est ouvert sur la fenêtre enfant

Nous sommes également confrontés à ce problème, mais je crois que c'est le résultat de la mise en œuvre de l'impression dans une nouvelle fenêtre et du fonctionnement de la prévisualisation D'impression de Chrome. Dans IE et Firefox, la fenêtre d'impression affiche le Dialogue modal, et vous n'êtes pas capable de faire n'importe quoi dans la fenêtre parent jusqu'à ce que la fenêtre d'impression soit fermée. De même, chrome bloque l'utilisation de la fenêtre parent jusqu'à ce que la prévisualisation de l'impression soit annulée. Toutefois, je m'attends à fermer l'onglet ou la fenêtre de travail de même que l'annulation de l'impression.

Quelqu'un d'autre a eu ce problème ou connaissez une bonne solution?

Merci!

41
demandé sur Community 2014-04-15 02:07:07

9 réponses

il semble que le problème ait été résolu avec la dernière mise à jour de Chrome... J'exécute la version Chrome 36.0.1964.4 dev - M.

j'ai été limité trop prévenir l'utilisateur de la fermeture de la fenêtre de prévisualisation d'impression en faisant ce qui suit:

if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1){   // Chrome Browser Detected?
    window.PPClose = false;                                     // Clear Close Flag
    window.onbeforeunload = function(){                         // Before Window Close Event
        if(window.PPClose === false){                           // Close not OK?
            return 'Leaving this page will block the parent window!\nPlease select "Stay on this Page option" and use the\nCancel button instead to close the Print Preview Window.\n';
        }
    }                   
    window.print();                                             // Print preview
    window.PPClose = true;                                      // Set Close Flag to OK.
}

maintenant, L'avertissement n'apparaît plus après la mise à jour de Chrome.

18
répondu Paul VB 2014-05-01 02:13:04

le problème est qu'il y a un dialogue d'impression dans la fenêtre popup. Si vous appelez window.close() immédiatement puis le dialogue n'est pas vu par l'utilisateur. L'utilisateur doit cliquer sur "Imprimer" dans le dialogue. Ce n'est pas la même chose que sur d'autres navigateurs où le dialogue d'impression fait partie du système D'exploitation, et bloque le window.close() jusqu'à ce qu'il soit rejeté - sur Chrome, C'est une partie de Chrome, pas le système d'exploitation.

C'est le code que j'ai utilisé, dans une petite fenêtre popup qui est créé par la fenêtre mère:

var is_chrome = function () { return Boolean(window.chrome); }
window.onload = function() {
    if(is_chrome){
        /*
         * These 2 lines are here because as usual, for other browsers,
         * the window is a tiny 100x100 box that the user will barely see.
         * On Chrome, it needs to be big enough for the dialogue to be read
         * (NB, it also includes a page preview).
        */
        window.moveTo(0,0);
        window.resizeTo(640, 480);

        // This line causes the print dialogue to appear, as usual:
        window.print();

        /*
         * This setTimeout isn't fired until after .print() has finished
         * or the dialogue is closed/cancelled.
         * It doesn't need to be a big pause, 500ms seems OK.
        */
        setTimeout(function(){
            window.close();
        }, 500);
    } else {
        // For other browsers we can do things more briefly:
        window.print();
        window.close();
    }
}
4
répondu Coder 2016-02-02 20:21:24

pour ceux d'entre vous qui sortent une nouvelle fenêtre pour imprimer à partir de, puis la fermer automatiquement après que l'utilisateur clique sur "Imprimer" ou "Annuler" sur la prévisualisation D'impression Chrome, j'ai utilisé ce qui suit (merci à L'aide de la réponse de PaulVB):

if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    var showPopup = false;
    window.onbeforeunload = function () {
        if (showPopup) {
            return 'You must use the Cancel button to close the Print Preview window.\n';
        } else {
            showPopup = true;
        }
    }
    window.print();
    window.close();
} else {
    window.print();
    window.close();
}

je me demande si ce serait une bonne idée de filtrer également par la version de Chrome...

1
répondu Primalpat 2014-05-20 20:22:34

Chrome print est habituellement une page d'extension de sorte qu'il n'y a pas de pièce jointe dom se produisant dans votre page existante. Vous pouvez déclencher la commande print en utilisant la ligne de commande apis(window.print()) mais ils n'ont pas fourni d'API pour la fermer en raison de raisons variables comme le choix des options d'impression, la machine d'impression,le comptage, etc.

0
répondu Venkatesh Nadar 2014-04-21 14:19:19

utilisez ce code pour retourner et recharger la fenêtre courante:

function printpost() {
  if (window.print()) {
    return false;
  } else {
    location.reload();
  }
}
0
répondu karthikeyan ganesan 2016-04-23 17:17:36

je peux confirmer que J'ai le même bug sur Windows 7 en utilisant Chrome Version 35, mais je partage ma solution partielle qui ouvre un nouvel onglet sur Chrome et affiche une boîte de dialogue.

pour autre navigateur lorsque l'utilisateur clique sur Annuler fermer automatiquement la nouvelle fenêtre d'impression.

//Chrome's versions > 34 is some bug who stop all javascript when is show a prints preview
///q/javascript-window-print-in-chrome-closing-new-window-or-tab-instead-of-cancelling-print-leaves-javascript-blocked-in-parent-window-68110/"stylesheet" type="text/css" href="style.css" />' +
        '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div></html>');
    popupWin.onbeforeunload = function (event) {
        return 'Please use the cancel button on the left side of the print preview to close this window.\n';
    };
}else {
    var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
    popupWin.document.write('<!DOCTYPE html><html><head>' +
        '<link rel="stylesheet" type="text/css" href="style.css" />' +
        '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div>' +
        '<script>setTimeout(function(){ window.parent.focus(); window.close() }, 100)</script></html>');
}
popupWin.document.close();
0
répondu Eduardo Chavira 2016-04-23 17:18:08

si la fonction setTimeout ne fonctionne pas pour vous non plus, alors faites ce qui suit:

//Create an iframe
iframe = $('body').append($('<iframe id="documentToPrint" name="documentToPrint" src="about:blank"/>'));
iframeElement = $('#documentToPrint')[0].contentWindow.document;

//Open the iframe
iframeElement.open();

//Write your content to the iframe
iframeElement.write($("yourContentId").html());

//This is the important bit.
//Wait for the iframe window to load, then print it.
$('#documentToPrint')[0].contentWindow.onload = function () {
    $('#print-document')[0].contentWindow.print();
    $('#print-document').remove();
};
iframeElement.close();
0
répondu Daybreak 2016-08-23 11:24:12

OK voilà ce qui a fonctionné pour moi! J'ai un bouton sur mon menu de navigation de gauche. Si vous cliquez il ouvrira une fenêtre et cette fenêtre chargera un document. Après avoir chargé le document je veux imprimer le document puis fermer la fenêtre popup immédiatement.

contentDiv.focus();
contentDiv.contentWindow.print();
contentDiv.contentWindow.onfocus = function() {
    window.close();
};

pourquoi ça a marché?

Après l'impression, vous réglez l'événement onfocus pour fermer la fenêtre. Le popup d'impression se chargera si rapidement que l'événement onfocus n'aura pas la chance de déclenchez jusqu'à 1)imprimez 2) annulez l'impression. Une fois que vous regagnez la concentration à la fenêtre, la fenêtre se fermera!

j'espère que cela fonctionnera pour vous

0
répondu AhmedGadir 2017-04-25 21:40:10

j'ai mandained d'une même page (asp classique...)

mon approche consistait à utiliser Q promise directement sur le popup.

par exemple mon problème était que le popup que je voulais Imprimer se ferme trop vite ... et l'impression previw était vide, j'ai résolu de cette façon :

appelant:

var popup = window.open("index.asp","popupwindow","width=800,height=500,left=200,top=5,scrollbars,toolbar=0,resizable");

Popup (à la fin de la page):

<script src="/Scripts/jquery-1.9.1.min.js"></script>
<script src="/Scripts/q.min.js"></script>
<script type="text/javascript">
    Q(window.print()).then(function () {window.close();});
</script>

je pense que votre " parent lock" pourrait être résolu d'une manière similaire

je voudrais essayer :

var w = whatever;
Q(
  // fill your popup
).then(function () {
 w.print();
}).then(function () {
 w.close();
}); 

qui rend "l'impression" et de "la fermer" async... ainsi, le parent sera immédiatement "déverrouillé "

-1
répondu nrgjack 2014-04-29 15:15:26