Печать содержимого динамически созданного iframe из родительского окна

У меня есть страница со списком ссылок и div, который служит заполнителем для страниц, на которые ведут ссылки. Каждый раз, когда пользователь нажимает на ссылку, в div создается iframe, а его атрибут src получает значение атрибута href ссылки — простой и понятный вид галереи внешних веб-страниц. У меня проблема с печатью содержимого iframe. Для этого я использую этот код:

function PrintIframe()  
{  
frames["name"].focus();  
frames["name"].print();  
}

Похоже, проблема в том, что iframe создается JQuery динамически - когда я вставляю iframe прямо в html-код, браузер нормально печатает внешнюю страницу. Но с тем же кодом, введенным JavaScript, ничего не происходит. Я пытался использовать «живое» событие JQ 1.3 по ссылке «Печать», но безуспешно. Есть ли способ преодолеть это?


person certainlyakey    schedule 06.05.2009    source источник


Ответы (8)


Предположим, что вот так выглядит ваш iframe:

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

Вот как вы это делаете с помощью jQuery:

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

и вот как вы это делаете, используя собственный JavaScript:

document.getElementById("print-iframe").contentWindow.print();
person Fareed Alnamrouti    schedule 10.03.2012

Я попробовал это и смог воспроизвести проблему. Я заметил, что при вызове функции печати iframe не был загружен. я проверил это, проверив значение innerHTML при вызове PrintIFrame(). Чтобы преодолеть это, вы можете использовать setTimeOut для повторного вызова функции через x миллисекунд:

function PrintIframe() { 

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

Это сработало для меня

EDIT Странно - в моем тестовом коде было предупреждение, которое, кажется, заставляет его работать. Когда я его вынул, он не работал. Извини :(

В любом случае, это должно сделать это с помощью jQuery, чтобы прикрепить обработчик события загрузки к iframe. Я тестировал IE8, и он работает:

<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>
person Temple    schedule 06.05.2009
comment
Не для меня :( Опять же, с html все в порядке, но он не печатает iframe, если он был создан самим JQ. - person certainlyakey; 07.05.2009
comment
Что ж, ваша последняя разработка сработала для меня на тестовой странице, следует исследовать дальше... - person certainlyakey; 10.05.2009
comment
Это решение сработало для меня. специально функция iframe.load является ключом к решению. - person SSD; 23.06.2021

У меня возникла проблема с печатью содержимого iframe. Для этого используйте код ниже:

Например, у вас есть iframe:

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

Затем js для печати содержимого iframe вызывает эту функцию (работает как в ie, так и в других браузерах):

printIframe('print-iframe');

Код функции:

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();
    }
}
person Yuri    schedule 28.10.2013
comment
Кажется, это работает нормально. Однако я думаю, что лучше проверить наличие (msie›-1). - person Valdez V.; 29.11.2013
comment
Это только простая проверка :) Источник: support.microsoft.com/kb/167820 - person Yuri; 15.12.2013
comment
Это работает только один раз. Если я нажму кнопку еще раз, я получу ошибку времени выполнения JavaScript: Доступ запрещен. Я пытаюсь распечатать PDF-документ без вывода сообщений. У меня есть таблица с несколькими записями, и каждую запись можно распечатать. Когда нажимается кнопка печати записи, src iframe обновляется новым URL-адресом, и приведенный выше код выполняется для его автоматической печати. Как я уже сказал, он работает один раз, но при последующих щелчках происходит сбой с указанной выше ошибкой javascript. - person Paul; 29.01.2018

Хм, я правильно понял? Вам нужно только изменить источник, куда ведет IFrame?

$("#iframe").attr("src", "http://www.example.com");
person Ólafur Waage    schedule 06.05.2009
comment
нет, проблема в том, что я не могу распечатать страницу в iframe - есть 2 варианта: 1) можно распечатать как часть страницы (плагином PrintArea) - но тогда печатается только одна страница и содержимое iframe страницы не отформатирована на бумаге должным образом. 2) его можно распечатать как обычную страницу, но ТОЛЬКО если тег iframe не вставляется динамически, через JS, а статически присутствует в HTML. - person certainlyakey; 06.05.2009

Возможно, ограничение того же домена препятствует выполнению вашего JavaScript. Ограничение одного и того же домена позволяет JavaScript в фрейме A (или главном окне) взаимодействовать (например, .print()) с фреймом B, если A и B находятся в одном домене. Проверьте консоль ошибок JavaScript. Если вы получаете что-то вроде исключения безопасности/ошибки разрешения, то, скорее всего, это связано с ограничением того же домена.

person pts    schedule 06.05.2009
comment
Нет, у меня в Firebug таких ошибок нет... И да, страницы все с одного домена. - person certainlyakey; 06.05.2009

Я нашел это поиском в Интернете

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

и изменил его на

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

twigstechtips

person blomman9    schedule 10.12.2012

Я знаю, что это довольно старый поток, но у меня есть более надежное решение для этого.

Он основан на https://stackoverflow.com/a/9648159/3183069 и https://stackoverflow.com/a/831547/3183069

Я добавил функцию .one(), чтобы она не зацикливалась бесконечно, если вы отмените печать! Я также загружаю iframe один раз. Наслаждаться

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" />

person JFK    schedule 04.10.2017

Это довольно старый поток, но я нашел одно рабочее решение для этого.

Я добавил сон в jquery, чтобы он не печатал пустое окно, для перезагрузки недавно замененного содержимого требуется несколько секунд.

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