开发者

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. After testing a lot of approaches (some of which also found on this site), my current approach seems to work quite good cr开发者_JAVA技巧oss-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. The iPad prints the page which contains the iFrame, instead of the contents of the iFrame. Safari on Mac correctly prints the contents of the iFrame, though.

Has anyone already solved this problem and been able to print the contents of an iFrame on an iPad?


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:

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.

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:

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.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜