Проблема заключается в том, что браузеры используют ширину iframe контейнера, чтобы определить, как масштабировать содержимое этого фрейма для печати. Следовательно, ширина кадров должна быть явно определена.
К сожалению, динамическое вычисление ширины печати довольно сложно и требует некоторых хакерских действий. Возможно, было бы лучше просто стилизовать фиксированную ширину страниц компонента и жестко задать для нее ширину 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, так как они не поддерживают inline-block
. (Есть также несколько других старых браузеров, которые тоже этого не делают). Можно, конечно, попробовать
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 обрабатывает display: inline-block
и white-space: nowrap
иначе, чем Chromium / WebKit для элементов фиксированной ширины (именно поэтому один документ выглядел по-настоящему шатким с предыдущим кодом). Далее следует отметить, что Firefox любит вносить небольшой запас в свои фреймы. Я не очень знаком с кодом Firefox, который делает это (провожу свои дни, взламывая Chromium), но мое обычное решение (кроме того, чтобы избегать фреймов) - просто добавить дополнительные 25px на полях. Такая небольшая сумма, кажется, популярна, чтобы решить эту проблему.
Теперь части кода, которые на самом деле лучше:
Во-первых, теперь в нем хранится старое тело, он поднимает тело на div для измерения, а затем восстанавливает старое тело. Это должно избежать проблем с негибким CSS и должно гарантировать более предсказуемое поведение. Во-вторых, это теперь делает то же самое для высоты и ширины (мое предыдущее предположение, что жестко запрограммированные ширины просто сработали бы, было бесполезно, и в любом случае это более гибкое решение).
Почему это все еще плохо?
Удаление white-space: nowrap
приведет к переносу текста при печати в Chromium / WebKit. Он по-прежнему печатается нормально, но это не совсем правильно, поскольку какой-то дополнительный текст будет перенесен. Чтобы сделать это действительно работоспособным решением, вам все равно придется выполнять код, определяющий браузер.
Опять же, я рекомендую использовать этот код для быстрого определения подходящей ширины и высоты, а затем для проверки и жесткого кодирования правильных размеров для каждого браузера. Это уродливое решение, но в конечном итоге это единственное действительно надежное решение в этой ситуации.