最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Printing Iframe in IE 11 only prints first page - Stack Overflow

programmeradmin3浏览0评论

I have the following code to print the content of a popup window:

var frame = this._urlElement;
if (frame) {
    var content = frame.contentWindow.document.getElementById("content");
    if (content) {
        MarvalSoftware.UI.Dom.setStyles(content, { 'overflow': 'visible' });
    }
    frame.contentWindow.focus();
    frame.contentWindow.print();
}

where _urlElement is an iframe, and its content doc has overflow: auto. When I print to PDF in IE11, I only see the first page, and the content is not cleanly cut off, nor are any scrollbars visible on the printed PDF. If I try Print Preview, even inside the iframe, I see the whole page with the outline of the popup window.

The page I am trying to print from the Iframe has a master page, with a content div with overflow: auto. When I print like that, Chrome and IE, I see a scrollbar on the print-out, and the print-out is only one page, so in my page's stylesheet, I override that overflow rule with a media query for print, to overflow: visible. Then, when I print on Chrome, the scrollbar is gone, and the printout is two pages. In IE, the scrollbar is also gone, but the print-out is unceremoniously cut off at the end of printed page 1.

When I modify my print code to create a new IFrame, and insert it into the document to be printed, copy the stylesheets and body over to the new iframe, and print the new iframe, then even on IE, the full document is printed. That is, the new iframe is not contained in any elements of the master page, so, is there any other styling in the master page I can look for that could cause this, other than overflow?

BTW, I seem to only experience this behaviour when I print to PDF, using Windows's own 'PDF printer'.

I have the following code to print the content of a popup window:

var frame = this._urlElement;
if (frame) {
    var content = frame.contentWindow.document.getElementById("content");
    if (content) {
        MarvalSoftware.UI.Dom.setStyles(content, { 'overflow': 'visible' });
    }
    frame.contentWindow.focus();
    frame.contentWindow.print();
}

where _urlElement is an iframe, and its content doc has overflow: auto. When I print to PDF in IE11, I only see the first page, and the content is not cleanly cut off, nor are any scrollbars visible on the printed PDF. If I try Print Preview, even inside the iframe, I see the whole page with the outline of the popup window.

The page I am trying to print from the Iframe has a master page, with a content div with overflow: auto. When I print like that, Chrome and IE, I see a scrollbar on the print-out, and the print-out is only one page, so in my page's stylesheet, I override that overflow rule with a media query for print, to overflow: visible. Then, when I print on Chrome, the scrollbar is gone, and the printout is two pages. In IE, the scrollbar is also gone, but the print-out is unceremoniously cut off at the end of printed page 1.

When I modify my print code to create a new IFrame, and insert it into the document to be printed, copy the stylesheets and body over to the new iframe, and print the new iframe, then even on IE, the full document is printed. That is, the new iframe is not contained in any elements of the master page, so, is there any other styling in the master page I can look for that could cause this, other than overflow?

BTW, I seem to only experience this behaviour when I print to PDF, using Windows's own 'PDF printer'.

Share Improve this question edited Nov 24, 2015 at 20:57 user990423 1,3892 gold badges13 silver badges32 bronze badges asked Nov 16, 2015 at 12:24 ProfKProfK 51.1k126 gold badges415 silver badges800 bronze badges 16
  • 1 @HiddenHobbes I have provided the JavaScript, but this is a massive ten year old legacy project. For me to provide the other code would take hours, and pages and pages. I am trying to replicate in a new page without legacy master pages and if necessary I will supply that. – ProfK Commented Nov 18, 2015 at 13:31
  • 3 That would be good, without seeing the exact problem it will be difficult to provide a useful solution for your particular issue. – Hidden Hobbes Commented Nov 18, 2015 at 13:43
  • 1 @MarcosRegis I have, as I said in the question. I override the master page's content: { overflow: auto; } to @media print { content: { overflow: visible; } }, but that just stops the printed page on any browser having a scrollbar and not showing all. – ProfK Commented Nov 18, 2015 at 14:43
  • 1 Is the print being called from the iframe, or from the page that contains the iframe? I wonder if that might make a difference. Just a guess. – deebs Commented Nov 18, 2015 at 14:51
  • 1 I'm pretty new to all of this still so bear with me, but could this make a difference... -ms-overflow-style: none (from msdn.microsoft.com/en-us/library/windows/apps/hh441298.aspx). Sounds like it's more of an issue with the Windows PDF printer than the CSS of the page – deebs Commented Nov 18, 2015 at 15:54
 |  Show 11 more comments

2 Answers 2

Reset to default 16 +500

Most likely cause: absolute positioning

Based on the problem description and OP's comments, I suspect the #content element and/or one or more of its ancestor elements (possibly including body or html) has the CSS property/value position: absolute;. This tends to cause Internet Explorer to cut off everything after the first page, while other browsers print everything.

Solution: The easiest solution would be remove the absolute positioning, at least for print media. If that's not an option, then the alternative would be to adjust the CSS height property of the absolutely positioned element(s). Without seeing the markup and CSS, I can't say what height needs to be set on which element(s), but chances are, it's going to be either 100% or auto, or some combination of the two.


Other possibility: iframe losing focus

If the iframe's focus is being lost somehow before the print() function fires, it could cause the sort of browser-specific behavior described in the OP. Most browsers will print an iframe's content if you call the print() function as a method of the iframe's contentWindow. IE, on the other hand, will always print whatever window is currently in focus*.

Solution: Instead of having the print function print the iframe directly, have it embed a temporary print button and trigger it with a virtual click, like so:

var frame = this._urlElement;
if (frame) {
    var content = frame.contentWindow.document.getElementById("content");
    if (content) {
        MarvalSoftware.UI.Dom.setStyles(content, { 'overflow': 'visible' });
    }
    frame.contentDocument.body.insertAdjacentHTML(
      'beforeend',
      '<div id="print" onclick="window.focus();window.print();"></div>'
    );
    var printButton = frame.contentDocument.getElementById('print');
    printButton.click();
    printButton.parentNode.removeChild(printButton);
}

This doesn't actually eliminate the need to set the focus, but I figured it might be worth a try since the OP indicated in his comments that the printing works when triggered from within the iframe.

Alternative solution: This one works by temporarily replacing the parent document with the iframe's document. It does eliminate the need to focus on the iframe, but it's a much more extreme solution, and I'd expect to run into some issues with very large and complex pages.

var frame = this._urlElement;
if (frame) {
    var content = frame.contentWindow.document.getElementById("content");
    if (content) {
        MarvalSoftware.UI.Dom.setStyles(content, { 'overflow': 'visible' });
    }
    var doc = document.documentElement;
    document.replaceChild(frame.contentDocument.documentElement, doc);
    window.setTimeout(function() {
        window.print();
        document.replaceChild(doc, document.documentElement);
    }, 100);
}

* When printing from the user interface, IE always prints the top level window by default. To print an iframe's content, you have to select it (e.g. by clicking in the frame and hitting CTRL+A) and then choose "Selected" in the print dialog, or "As selected on screen" in the print preview.

try this:

var content = document.getElementById('content');

try {
    content.contentWindow.document.execCommand('print', false, null);
} catch (e) {
    content.contentWindow.print();
}          
发布评论

评论列表(0)

  1. 暂无评论