2016-01-28 9 views
10

Mam komponent galerii, który wykorzystuje bieżący rozmiar okna, aby określić, jak duże są elementy galerii. Podłączyłem także zdarzenia zmiany rozmiaru okna, aby zmienić rozmiar elementów galerii podczas zmiany rozmiaru okna.Ponownie wyrenderuj komponenty Reactjs do wydrukowania

W przeglądarce Chrome, jeśli użytkownik wydrukuje galerię, elementy nie zostaną zmienione, aby pasowały do ​​drukowanej strony. Zamiast tego używają tylko ostatniego rozmiaru obliczonego dla rozmiaru okna. Dzieje się tak nawet w przypadku przełączania z opcji pionowej na poziomą w opcjach drukowania.

Czy istnieje sposób na wymuszenie reakcji na ponowne renderowanie komponentów podczas otwierania okna dialogowego drukowania i przy zmianie układu strony z portretu na krajobraz? Sądziłem, że okno dialogowe drukowania ponownie wyświetli stronę z nowymi wymiarami, ale wydaje się, że tak nie jest.

+0

Jeśli układ reaguje na zmianę rozmiarów okna, dlaczego nie wystarczy użyć CSS drukowania, aby zmienić rozmiar okna, a tym samym zmienić układ strony? –

+0

Czy istnieje sposób na określenie rozmiaru i orientacji papieru? W przeciwnym razie musiałbym twardo zakodować pojedynczą wartość, która nie zawsze dawałaby prawidłowe wyniki. – Bill

Odpowiedz

5

Podczas drukowania strony przeglądarka wykonuje migawkę bieżącego modelu DOM i stosuje style nośnika print. Twoim problemem są elementy w twoim DOM zależne od wymiarów ekranu.

Zdarzenia zmiany rozmiaru okna pomogą zmienić układ komponentów, gdy użytkownik zmieni rozmiar ekranu, ale nie są one wyzwalane, gdy użytkownik drukuje. Istnieją jednak sposoby, w których można słuchać zdarzenia, gdy użytkownik wydrukuje stronę.

window.onbeforeprint uruchomi się, gdy użytkownik wydrukuje stronę. W przypadku zdarzenia można zmienić rozmiar ekranu, aby zdarzenia zmiany rozmiaru okna wyzwoliły lub ponownie renderowały komponenty w inny sposób. Nie jest obsługiwany w chrome, chociaż spójrz na this stackoverflow post, wyjaśnia, w jaki sposób można zamiast tego użyć window.matchMedia('print').

Zawsze lepiej polegać na zapytaniach o media CSS niż na wymiary ekranu i zmieniać rozmiar zdarzeń, ale czasami nie zawsze jest to możliwe.

+0

Dzięki za Marc, znalazłem to pomocne. Dodałem detektor do window.matchMedia ('print') w komponencie componentWillMount, który zmienia właściwość 'isPrinting' w stanie na true lub false w zależności od tego, czy zapytanie jest dopasowane, a następnie wywołuje forceUpdate(). Jednak ponowne uruchomienie wyzwolone przez forceUpdate następuje tylko po zamknięciu okna dialogowego drukowania, w którym to momencie nośnik zostanie ponownie zmieniony. –

+0

Nie ma za co. @ThomasHopkins, cieszę się, że mogłem pomóc. To dobre rozwiązanie, może możesz opublikować kod dla innych, aby zobaczyć, jak to działa. –

+1

Dzięki @MarcGreenstock, ale niestety to nie jest rozwiązanie. Ponowne renderowanie, które powinno się zdarzyć w forceUpdate, jest wykonywane tylko po zamknięciu okna dialogowego drukowania, kiedy to jest już za późno! –

1

Musisz użyć interfejsu API matchMedia w swoim komponencie. Ale robiąc to sam, będziesz ponownie wymyślać całą masę koła. Łatwiej byłoby użyć istniejącej biblioteki, która się tym zajmuje. Proszę sprawdzić https://www.npmjs.com/package/react-responsive. Zawiera komponenty opakowaniowe oparte na React na matchMedia, więc powinieneś być w stanie szybko go prototypować w swoim projekcie. Dostępne są także wielokątki. Kolejną zaletą jest to, że w interfejsie możesz mieć opcję podglądu wydruku, dzięki której użytkownik może zobaczyć, jak galeria będzie wyglądać w trybie drukowania. W tym celu można użyć funkcji renderowania serwera tej biblioteki, aby symulować tryb drukowania.

PS: Nie jestem w żaden sposób związany z tym projektem.

3

Korzystanie zapytania mediów kierować pionowym i poziomym drukiem

@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

Ponadto rozwiązanie WitVault za I utworzeniu prostą React składnik, który sprawia, że ​​obsługa złożoną print.css znacznie łatwiejsze. Zamiast dodawania klas, identyfikatory itp całym znaczników i tworząc złożoną plik print.css, można korzystać z biblioteki reagować-drukującą następująco:

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

Dodaj ten identyfikator do korzenia (lub gdzieś wysoko w drzewie DOM) od aktualnej zawartości (ale wewnątrz w tagu ciała)

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

Dodaj div z id 'print-mount, czy cokolwiek zamontować identyfikator chcesz użyć .

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

Tworzenie struktury chcesz dla swojej wersji do druku (które mogą zawierać elementy podrzędne z własnych stylów, aby ułatwić.

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')); 

Zasadniczo, to czyni swoją wersję do druku, ale to ukryte dopóki Jeśli potrzebujesz tego do przesuwanej galerii, prawdopodobnie chcesz podłączyć się do zdarzenia zmiany suwaka i ponownie wyrenderować (odłączyć stary, zamontować nowy) szablon drukowania. to pomaga!