以下是我正在使用的文档的示例:http://dl.dropbox.com/u/291229/print-test/index.html
您可以在Firefox中进行打印预览,看看我的意思.如果您在其自己的选项卡/窗口中打开第一帧并打印预览,则轮廓框很适合页面.在iframe堆栈的父窗口中执行相同操作会显示在页面边界外部流动的单元格.
免责声明:我没有对这些页面进行编码.是的,我知道他们很可怕.遗憾的是,该项目没有时间或预算来重新编写页面,以实现打印一组文档的单页目标.我可能会暂时要求用户单独打印每个页面以进行适当的缩放,但我仍然想了解可能导致此问题的原因.
解决方法
不幸的是,动态计算打印宽度是相当棘手的,并涉及一些hackery.你可能最好只设置一个固定宽度的组件页面并将iframe宽度硬编码.
但是,如果您确实需要动态调整它们的大小,则可以在文档加载后运行以下代码(在Chrome中测试):
var iframes = document.getElementsByTagName("iframe"); for(var i = 0; i < iframes.length; ++i) { var curFrame = iframes[i]; var curBody = curFrame.contentDocument.body; curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden; white-space: nowrap;">' + curBody.innerHTML + '</div>'; var printContent = curFrame.contentDocument.getElementById("iframe-print-content"); var curWidth = printContent.offsetWidth + printContent.offsetLeft; iframes[i].style.width=(curWidth + "px"); }
运行后,您可以正常打印或调用window.print()或做任何你想做的事情.
注意:此方法对ie6或ie7不起作用,因为它们不支持内联块. (还有一些其他较旧的浏览器也没有).当然,你可以试试
display:-moz-inline-stack; display:inline-block; zoom:1; *display:inline; overflow:hidden; white-space: nowrap;
相反,它可能会照顾大多数这些情况,但我对旧版浏览器不做任何承诺.
编辑:上面的解决方案在Firefox中有点不稳定.
Firefox解决方案(在Firefox 5中测试和使用):
var iframes = document.getElementsByTagName("iframe"); for(var i = 0; i < iframes.length; ++i) { var curFrame = iframes[i]; var curBody = curFrame.contentDocument.body; var oldHTML = curBody.innerHTML; curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden;">' + oldHTML + '</div>'; var printContent = curFrame.contentDocument.getElementById("iframe-print-content"); var curWidth = printContent.offsetWidth + printContent.offsetLeft + 25; var curHeight = printContent.offsetHeight + printContent.offsetTop + 25; curBody.innerHTML = oldHTML; iframes[i].style.width=(curWidth + "px"); iframes[i].style.height=(curHeight + "px"); }
有关此一般方法的工作原理的完整说明,请参阅上面的答案.
与上述解决方案有何不同,为什么?
首先,Firefox的具体内容:
有一些关键的区别.第一个是注意到Firefox处理显示:内联块和白色空间:现在与固定宽度元素的Chromium / WebKit不同(这就是为什么一个文档看起来真的很难用前面的代码).接下来注意到Firefox喜欢在其iframe中提供一点保证金.我不太熟悉执行此操作的Firefox代码(花费我的时间来攻击Chromium),但我通常的解决方案(除了避免使用框架)只是在边距上额外增加25px.像这样的一点点似乎是解决这类问题的流行黑客.
现在,代码的部分实际上更好:
首先,它现在存储旧体,将身体抬到div上进行测量,然后恢复旧体.这应避免CSS不灵活的问题,并应保证更可预测的行为.其次,现在对于高度和宽度做同样的事情(我之前的假设是硬编码的宽度才起作用并不好,无论如何这是一个更灵活的解决方案).
为什么这还不错?
带走白色空间:nowrap将在Chromium / WebKit上打印文本.它仍然打印很好,但它不完全正确,因为一些额外的文本将包装.要使这成为一个真正可行的解决方案,您仍然需要执行浏览器检测代码.
同样,我建议使用此代码快速找出适当的宽度和高度,然后测试并硬编码每个浏览器的正确大小.这是一个丑陋的解决方案,但它最终是这种情况下唯一真正强大的解决方案.