Повторное отображение компонентов Reactjs для печати

У меня есть компонент галереи, который использует текущий размер окна, чтобы определить, насколько большой размер элементов галереи. Я также подключил события изменения размера окна, чтобы элементы галереи были правильно изменены при изменении размера окна.

В Chrome, если пользователь печатает галерею, элементы не изменяются в соответствии с печатной страницей. Вместо этого они просто используют последний размер, рассчитанный для размера окна. Это справедливо даже при переключении с портретов в альбом в параметрах печати. ​​

Есть ли способ принудительно реагировать на повторную визуализацию компонентов, когда открывается диалоговое окно печати и когда макет страницы переключается с портрета на пейзаж? Я думал, что диалоговое окно печати повторно отобразит страницу с новыми измерениями, но это, похоже, не так.

Ответ 1

Когда вы печатаете страницу, браузер делает снимок текущей DOM и применяет стили носителя print. Ваша проблема заключается в том, что элементы вашего DOM зависят от размеров экрана.

События изменения размера окна помогут изменить порядок ваших компонентов, когда пользователь изменяет размер экрана, но они не запускаются, когда пользователь печатает. Однако существуют способы прослушивания события, когда пользователь печатает страницу.

window.onbeforeprint вызывается, когда пользователь печатает страницу. При событии вы либо изменяете размер экрана, чтобы события изменения размера окна запускали или повторно отображали ваши компоненты каким-либо другим способом. Он не поддерживается в chrome, но посмотрите fooobar.com/questions/137869/..., в нем объясняется, как вы можете использовать window.matchMedia('print') вместо этого.

Всегда лучше полагаться на запросы css media, а не на размер экрана и изменять размер событий, но иногда это не всегда возможно.

Ответ 2

Использовать медиа-запрос для ориентации портретной и альбомной печати

@media print and (orientation: landscape) {
    /* landscape styles */
    /* write specific styles for landscape e.g */
    h1 {
         color: #000;
         background: none;
      }

      nav, aside {
         display: none;
      }

   }

@media print and (orientation: portrait) {
    /* portrait styles */
}

Ответ 3

В дополнение к решению WitVault я создал простой компонент React, который упрощает обработку сложного print.css. Вместо добавления классов, идентификаторов и т.д. По всей разметке и создания сложного файла print.css вы можете использовать мою библиотеку ответов-печати следующим образом:

https://github.com/captray/react-print

Добавьте этот идентификатор в корень (или где-то высоко в вашем дереве DOM) вашего текущего содержимого (но внутри тега body)

<div id="react-no-print"> 

Добавьте div с идентификатором "print-mount" или любым другим идентификатором mount, который вы хотите использовать.

<div id="print-mount"></div>

Создайте структуру, которую вы хотите для своей версии для печати (которая может включать дочерние компоненты со своими собственными стилями, чтобы упростить процесс.

var PrintTemplate = require('react-print');
var ReactDOM = require('react-dom');
var React = require('react');

var MyTemplate = React.createClass({
    render() {
        return (
            <PrintTemplate>
                Your custom HTML or React Components go here, and will replace the existing HTML inside of the "react-no-print" ID, and instead it will render what inside of your custom template.
            </PrintTemplate>
        );
    }
});

ReactDOM.render(<MyTemplate/>, document.getElementById('print-mount'));

В принципе, это делает вашу версию для печати, но она скрыта до тех пор, пока она не понадобится для печати. Если вам нужно это для скользящей галереи, вы, вероятно, захотите подключить событие изменения для своего слайдера и повторно отобразить (отключить старый, установить новый) шаблон печати. ​​

Надеюсь, это поможет!

Ответ 4

Вам нужно будет использовать API matchMedia в вашем компоненте. Но, делая это самостоятельно, вы будете изобретать много колес. Было бы проще использовать существующую библиотеку, которая позаботится об этом. Проверьте https://www.npmjs.com/package/react-responsive. Он имеет компоненты оболочки на основе React по matchMedia, поэтому вы сможете быстро прототипировать его в свой проект. Также имеются полисы. Еще одно преимущество, которое я могу себе представить, заключается в том, что у вас может быть опция предварительного просмотра печати в вашем интерфейсе, где вы можете позволить пользователю просмотреть, как галерея будет выглядеть в режиме печати. Для этого вы можете использовать функцию рендеринга сервера этой библиотеки для имитации режима печати. ​​

PS: Я никоим образом не связан с этим проектом.