2016-01-28 3 views
10

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

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

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

+0

Если макет реагирует на изменение размера окна, почему бы просто не использовать CSS для печати, чтобы изменить размер окна и тем самым изменить расположение макета? –

+0

Есть ли способ рассказать размер и ориентацию бумаги? В противном случае мне пришлось бы жестко кодировать одно значение, которое не всегда приводило бы к правильным результатам. – Bill

ответ

5

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

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

window.onbeforeprint будет вызываться, когда пользователь распечатает страницу. При событии вы либо изменяете размер экрана, чтобы события изменения размера окна запускали или повторно отображали ваши компоненты каким-либо другим способом. Он не поддерживается в хроме, хотя взгляните на this stackoverflow post, он объясняет, как вы можете использовать window.matchMedia('print').

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

+0

Спасибо, Marc, я нашел это полезным. Я добавил слушателя в window.matchMedia ('print') в составе componentWillMount, который изменяет свойство isPrinting в состоянии на true или false в зависимости от того, соответствует ли запрос, а затем вызывает forceUpdate(). Тем не менее, повторный запуск, вызванный forceUpdate, происходит только после закрытия диалогового окна печати, после чего носитель снова изменяется. –

+0

Добро пожаловать @ Томас Хопкинс, рад, что смогу помочь. Кстати, это хорошее решение, возможно, вы можете опубликовать код для других, чтобы узнать, как это работает. –

+1

Спасибо @MarcGreenstock, но, к сожалению, это не решение. Повторный рендеринг, который должен произойти в forceUpdate, выполняется только после закрытия диалогового окна печати, и к этому времени уже слишком поздно! –

1

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

PS: Я не являюсь аффилированным лицом этого проекта.

3

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

@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, я создал простой Реагировать компонент, который делает обработку сложной print.css гораздо проще. Вместо того чтобы добавлять классы, идентификаторы и т.д. всю разметку и создание сложного print.css файла, вы можете использовать мою библиотеку реагировать-печать следующим образом:

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

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

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

Добавить DIV с идентификатором «распечаткой монтировки», или что-то монтировать ID вы хотите использовать ,

<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's inside of your custom template. 
      </PrintTemplate> 
     ); 
    } 
}); 

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

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

Надежда это помогает!

Смежные вопросы