jQuery 从父窗口打印动态创建的 iframe 的内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/831147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:53:11  来源:igfitidea点击:

Printing contents of a dynamically created iframe from parent window

jqueryiframeprinting

提问by certainlyakey

I have a page with a list of links and a div which serves as a placeholder for the pages the links lead to. Everytime user clicks on a link an iframe is created in the div and its src attribute gets the value of the link href attribute - simple and clear, sort of external web pages gallery. What i do have a problem with is printing the contents of the iframe. To do this i use this code:

我有一个页面,其中包含一个链接列表和一个 div,它用作链接指向的页面的占位符。每次用户单击链接时,都会在 div 中创建一个 iframe,其 src 属性获取链接 href 属性的值 - 简单明了,类似于外部网页图库。我确实有问题是打印 iframe 的内容。为此,我使用以下代码:

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

The issue seems to be that iframe is created dynamically by JQuery - when I insert an iframe right into the html code, the browser prints the external page all right. But with the same code injected by JavaScript nothing happens. I tried to use JQ 1.3 'live' event on "Print" link, no success. Is there a way to overcome this?

问题似乎是 iframe 是由 JQuery 动态创建的 - 当我将 iframe 插入到 html 代码中时,浏览器会正常打印外部页面。但是使用 JavaScript 注入的相同代码没有任何反应。我尝试在“打印”链接上使用 JQ 1.3 'live' 事件,但没有成功。有没有办法克服这个问题?

回答by Fareed Alnamrouti

Suppose that this is what your iframe looks like:

假设这是您的 iframe 的样子:

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

This is how you do it using jQuery:

这是使用 jQuery 的方法:

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

and this is how you do it using native JavaScript:

这就是你如何使用原生 JavaScript 做到这一点:

document.getElementById("print-iframe").contentWindow.print();

回答by Yuri

I've had an issue with printing iframe's content. In order to achive this, use code below:

我在打印 iframe 的内容时遇到了问题。为了实现这一点,请使用以下代码:

For example you have iframe:

例如你有 iframe:

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

Then js to print iframe's content call this function (works both in ie and other browsers):

然后 js 打印 iframe 的内容调用这个函数(在 ie 和其他浏览器中都有效):

printIframe('print-iframe');

Function's code:

函数代码:

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();
    }
}

回答by Temple

I tried this and was able to replicate the issue. What i noticed was that when calling the print function the iframe hadn't completed loaded. i tested this by checking the value of innerHTML when calling PrintIFrame(). To overcome this, you can use setTimeOut to call the function again x milliseconds later:

我试过这个并且能够复制这个问题。我注意到的是,在调用打印函数时,iframe 尚未完成加载。我通过在调用 PrintIFrame() 时检查 innerHTML 的值来测试这一点。为了克服这个问题,您可以使用 setTimeOut 在 x 毫秒后再次调用该函数:

function PrintIframe() { 

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

This worked for me

这对我有用

EDITStrange - i had an alert in my test code which seems to make it work. When i took it out, it didn't work. Sorry :(

编辑奇怪 - 我的测试代码中有一个警报,这似乎使它起作用。当我拿出来时,它不起作用。对不起 :(

Anyway, this should do it using jQuery to attach a load event handler to the iframe. I have tested on IE8 and it works:

无论如何,这应该使用 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>

回答by Kiwad

I know this is a pretty old thread but I have a more rubust solution for this.

我知道这是一个很旧的线程,但我有一个更可靠的解决方案。

It's based on https://stackoverflow.com/a/9648159/3183069and https://stackoverflow.com/a/831547/3183069

它基于 https://stackoverflow.com/a/9648159/3183069https://stackoverflow.com/a/831547/3183069

I added .one() function so it doesnt loop infinitely if you cancel the print! I also load the iframe once. Enjoy

我添加了 .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" />

回答by Amit Gupta

This is a pretty old thread but I found one working solution for this.

这是一个非常古老的线程,但我为此找到了一个可行的解决方案。

I added sleep in jquery so it doesn't print empty window, it requires few second to reload the newly replaced content.

我在 jquery 中添加了 sleep 所以它不会打印空窗口,它需要几秒钟来重新加载新替换的内容。

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

回答by ólafur Waage

Hmm do I get this right? You only need to change the source of where the IFrame leads to?

嗯,我说得对吗?您只需要更改 IFrame 导致的来源?

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

回答by pts

Maybe the same-domain restriction prevents your JavaScript from executing. The same-domain restriction allows JavaScript in frame A (or the main window) to interact (such as .print()) with frame B if A and B are from the same domain. Check your JavaScript error console. If you get something like a security exception / permission error, then it is most probably because of the same-domain restriction.

也许同域限制会阻止您的 JavaScript 执行。如果 A 和 B 来自同一域,则同域限制允许框架 A(或主窗口)中的 JavaScript 与框架 B 交互(例如 .print())。检查您的 JavaScript 错误控制台。如果您收到类似安全异常/权限错误的消息,那么很可能是因为同域限制。

回答by Igor Parra

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();
}

回答by blomman9

I found this searching the web

我在网上找到了这个

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

and changed it to

并将其更改为

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

twigstechtips

twigstechtips