web-dev-qa-db-fra.com

Impression du contenu d'un iframe créé dynamiquement à partir de la fenêtre parente

J'ai une page avec une liste de liens et une div qui sert d'espace réservé pour les pages auxquelles les liens mènent. Chaque fois que l'utilisateur clique sur un lien, un iframe est créé dans la div et son attribut src obtient la valeur de l'attribut link href - une sorte de galerie de pages Web externes, simple et claire. Ce qui me pose problème, c’est l’impression du contenu de l’iframe. Pour ce faire, j'utilise ce code: 

 fonction PrintIframe () 
 {
 images ["nom"]. focus (); 
 cadres ["nom"]. print (); 
} 

Le problème semble être que iframe est créé dynamiquement par JQuery - lorsque j'insère un iframe dans le code html, le navigateur affiche la page externe dans son intégralité. Mais avec le même code injecté par JavaScript, rien ne se passe. J'ai essayé d'utiliser l'événement "en direct" JQ 1.3 sur le lien "Imprimer", sans succès. Y a-t-il un moyen de surmonter cela?

16
certainlyakey

Supposons que ceci ressemble à votre iframe:

<iframe id='print-iframe' name='print-frame-name'></iframe>

Voici comment vous le faites en utilisant jQuery:

$("#print-iframe").get(0).contentWindow.print();

et voici comment vous le faites en utilisant du JavaScript natif:

document.getElementById("print-iframe").contentWindow.print();
30
Fareed Alnamrouti

J'ai eu un problème avec l'impression du contenu d'iframe. Pour y parvenir, utilisez le code ci-dessous:

Par exemple, vous avez iframe:

<iframe id='print-iframe' name='print-iframe'></iframe>

Puis js pour imprimer le contenu d'iframe appelle cette fonction (fonctionne aussi bien dans ie et les autres navigateurs):

printIframe('print-iframe');

Code de la fonction:

function printIframe(iFrameId) {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf ("MSIE ");
    var iframe = document.getElementById(printFrameId);

    if (msie !== 0) {
        iframe.contentWindow.document.execCommand('print', false, null);
    } else {
        iframe.contentWindow.print();
    }
}
9
Yuri Kushch

J'ai essayé ceci et ai pu reproduire le problème. Ce que j’ai remarqué, c’est que lors de l’appel de la fonction d’impression, l’iframe n’était pas chargée. J'ai testé cela en vérifiant la valeur de innerHTML lors de l'appel de PrintIFrame (). Pour résoudre ce problème, vous pouvez utiliser setTimeOut pour appeler la fonction x millisecondes plus tard:

function PrintIframe() { 

        if (window.frames['myname'].innerHTML != "") {
            window.frames['myname'].focus();
            window.frames['myname'].print();
        } else {
            setTimeout(PrintIframe,1000);
        }    
    }

Cela a fonctionné pour moi

EDIT Strange - mon code de test contient une alerte qui semble le faire fonctionner. Quand je l'ai sorti, ça n'a pas marché. Pardon :(

Quoi qu'il en soit, cela devrait utiliser jQuery pour attacher un gestionnaire d'événements de chargement à l'iframe. J'ai testé sur IE8 et cela fonctionne:

<html>
<head>
    <script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript">
    function loadiFrame(src)
    {
        $("#iframeplaceholder").html("<iframe id='myiframe' name='myname' src='" + src + "' />");
    }

    $(function()
    {
        $("#printbutton").bind("click", 
            function() { 
                loadiFrame('test.aspx'); 
                $("#myiframe").load( 
                    function() {
                        window.frames['myname'].focus();
                        window.frames['myname'].print();
                    }
                 );
            }
        );
    });
    </script>    
</head>
<body>
    <input type="button" id="printbutton" value="Load iFrame" />
    <div id="iframeplaceholder"></div>
</body>
</html>
8
Temple

J'ai trouvé cela en cherchant sur le web 

$('#preview-iframe').contents().find('html').html(data); 

et l'a changé en

$('#preview-iframe').contents().find('html').html(data).after(function() {
    document.getElementById("preview-iframe").contentWindow.print();
});

twigstechtips

0
blomman9

Peut-être que la restriction du même domaine empêche votre JavaScript de s'exécuter. La restriction de même domaine permet à JavaScript dans le cadre A (ou la fenêtre principale) d'interagir (tel que .print ()) avec le cadre B si A et B appartiennent au même domaine. Vérifiez votre console d'erreur JavaScript. Si vous obtenez quelque chose comme une erreur d'exception/autorisation de sécurité, c'est probablement en raison de la restriction du même domaine.

0
pts

Je sais que c'est un très vieux fil mais j'ai une solution plus sérieuse pour cela. 

Il est basé sur https://stackoverflow.com/a/9648159/3183069 et https://stackoverflow.com/a/831547/3183069

J'ai ajouté la fonction .one () afin qu'elle ne boucle pas indéfiniment si vous annulez l'impression! J'ai également chargé l'iframe une fois. Prendre plaisir

var $body = $("body"),
  $iframe,
  loadiFrame = function(src) {
    if ($body.children('#full-prog').length == 0) {
      $body.append("<iframe id='full-prog' src='" + src + "' />");
      $iframe = $("#full-prog");
      $iframe.one('load', function() {
        $iframe.get(0).contentWindow.print();
      });
    } else {
      $iframe.get(0).contentWindow.print();
    }
  };

$("#printbutton").click(function() {
  loadiFrame('iframe source here');
});
#full-prog {
  overflow: hidden;
  position: absolute;
  width: 0;
  height: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="printbutton" value="Load iFrame" />

0
Kiwad
var ifrm = document.createElement("iframe");
// ifrm.style.display = "none";
document.body.appendChild(ifrm);
setTimeout(function() {
    $(ifrm).contents().find("body").html("my html content");
}, 1);
ifrm.onload = function() {
    ifrm.contentWindow.print();
}
0
Igor Parra

Hmm, je comprends bien? Vous devez seulement changer la source d'où mène l'IFrame?

$("#iframe").attr("src", "http://www.example.com");
0
Ólafur Waage

C'est un joli vieux fil mais j'ai trouvé une solution qui fonctionne pour cela.

J'ai ajouté sleep dans jquery pour ne pas imprimer la fenêtre vide, il faut quelques secondes pour recharger le contenu récemment remplacé.

$('#printiframe').attr('src', pdf_file_path);
setTimeout(function () {
     $("#printiframe").get(0).contentWindow.print();
}, 500);
0
Amit Gupta