简体   繁体   English

如何在iPad上使用Javascript打印iFrame的内容?

[英]How to print the contents of an iFrame using Javascript on iPad?

Printing the contents of an iFrame already seemed a challenging problem to solve cross-browser. 打印iFrame的内容已经成为解决跨浏览器的一个具有挑战性的问题。 After testing a lot of approaches (some of which also found on this site), my current approach seems to work quite good cross-browser and looks like this: 在测试了很多方法(其中一些也在这个网站上找到)之后,我目前的方法似乎工作得非常好,跨浏览器看起来像这样:

function printUrl( elem, url ) {
    $( '#' + elem ).append( "<iframe style='border: none; width: 0; height: 0; margin: 0; padding: 0;' src='" + url + "' id='printFrame'></iframe>" );

    $( '#printFrame' ).load( function() {
        var w = ( this.contentWindow || this.contentDocument.defaultView );
        w.focus();
        w.print();
    } );
}

There is only a slight problem with this code when using an iPad. 使用iPad时,此代码只有轻微问题。 The iPad prints the page which contains the iFrame, instead of the contents of the iFrame. iPad打印包含iFrame的页面,而不是iFrame的内容。 Safari on Mac correctly prints the contents of the iFrame, though. 不过,Mac上的Safari正确打印了iFrame的内容。

Has anyone already solved this problem and been able to print the contents of an iFrame on an iPad? 有没有人已经解决了这个问题,并能够在iPad上打印iFrame的内容?

Okay, first of all. 好的,首先。 I did not solve the problem. 我没有解决问题。 I created a work-around that actually fakes what I want to achieve. 我创建了一个解决方案,实际上伪造了我想要达到的目标。

Because the iPad / iPhone simple prints the parent page, I wrap the complete body in a new div, then append the iFrame and some stylesheets which make sure that the printed document only contains the iFrame: 因为iPad / iPhone简单打印父页面,我将整个主体包装在一个新的div中,然后附加iFrame和一些样式表,以确保打印文档只包含iFrame:

function printUrl( url ) {
    $newBody = "<div class='do_not_print_this'>"
                + $( 'body' ).html()
                + "</div>"
                + "<iframe style='border: none; 0; width: 100%; margin: 0; padding: 0;' src='" + url + "' class='printFrame'></iframe>"
                + "<style type='text/css' media='all'>.printFrame { position: absolute; top: -9999999px; left: -99999999px; }</style>"
                + "<style type='text/css' media='print'>.do_not_print_this { display: none; } .printFrame { top: 0; left: 0; }</style>";
    $( 'body' ).html( $newBody );

    $( '.printFrame' ).load( function() {
        var w = ( this.contentWindow || this.contentDocument.defaultView );
        w.focus();
        w.print();
    } );
}

Hiding the iframe for the browser in the normal view is done using absolute positioning, using display on none or visibility hidden introduced weird behavior in the final print. 在普通视图中隐藏浏览器的iframe是使用绝对定位完成的,使用无显示或隐藏可见性隐藏在最终打印中引入了奇怪的行为。

Yes, it's ugly. 是的,这很难看。 However, this is currently the only option I can think of which works. 但是,这是我能想到的唯一可行的选择。 If any of you come up with a better solution, please let me know. 如果您有任何人想出更好的解决方案,请告诉我。

Here's a function that works cross-cross platform on evergreen browsers and the current versions of iOS: 这是一个在常绿浏览器和iOS当前版本上运行跨平台的功能:

function printElement(divid, title)
{   
  var contents = document.getElementById(divid).innerHTML;
  var frame1 = document.createElement('iframe');
  frame1.name = "frame1";
  frame1.style.position = "absolute";
  frame1.style.top = "-1000000px";
  document.body.appendChild(frame1);
  var frameDoc = frame1.contentWindow ? frame1.contentWindow : frame1.contentDocument.document ? frame1.contentDocument.document : frame1.contentDocument;
  frameDoc.document.open();
  frameDoc.document.write('<html><head><title>' + title + '</title>');
  frameDoc.document.write('</head><body style="font-family: Arial, Helvetica, sans; font-size: 14px; line-height: 20px">');
  frameDoc.document.write('<h1>' + title + '</h1>');
  frameDoc.document.write(contents);
  frameDoc.document.write('</body></html>');
  frameDoc.document.close();

  setTimeout(function () {
    window.frames["frame1"].focus();
    window.frames["frame1"].print();
  }, 500);

  //Remove the iframe after a delay of 1.5 seconds
  //(the delay is required for this to work on iPads)
  setTimeout(function () {
     document.body.removeChild(frame1);
  }, 1500);
  return false;
}

This is based on this answer with minor modifications (Importantly the line document.body.removeChild(frame1); had to be removed to allow for printing on iOS.) 这是基于这个答案的微小修改(重要的是行document.body.removeChild(frame1);必须删除以允许在iOS上打印。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM