2016-01-28 9 views
10

ギャラリーアイテムを作成するために現在のウィンドウサイズを使用するギャラリーコンポーネントがあります。また、ウィンドウのサイズが変更されたときにギャラリーアイテムのサイズが正しく変更されるように、ウィンドウのサイズ変更イベントをフックしました。印刷用Reactjsコンポーネントを再レンダリング

Chromeでは、ユーザーがギャラリーを印刷すると、アイテムは印刷されたページに合わせてサイズ変更されません。代わりに、彼らはちょうどウィンドウサイズのために計算された最後のサイズを使用しています。これは、印刷オプションでポートレートからランドスケープに切り替えるときにも当てはまります。

印刷ダイアログを開いているときや、ページレイアウトをポートレートからランドスケープに切り替えたときに、コンポーネントを再レンダリングするように強制する方法はありますか?私は、印刷ダイアログが新しい次元でページを再描画すると思ったが、そうではないようだ。

+0

レイアウトがウィンドウのサイズ変更に反応する場合は、印刷CSSを使用してウィンドウのサイズを変更し、レイアウトを再配置するだけではいかがですか? –

+0

用紙のサイズや向きを伝える方法はありますか?それ以外の場合は、常に正しい結果を生成しない単一の値をハードコードする必要があります。 – Bill

答えて

5

ページを印刷すると、ブラウザは現在のDOMのスナップショットを取り、printメディアスタイルを適用します。あなたの問題は、DOMの要素が画面の大きさに依存していることです。

ウィンドウサイズ変更イベントは、ユーザーが画面のサイズを変更したときにコンポーネントを並べ替えるのに役立ちますが、ユーザーが印刷するときにトリガーされません。ただし、ユーザーがページを印刷するときにイベントを聴くことができます。

window.onbeforeprintユーザーがページを印刷するときにトリガーされます。イベントでは、画面のサイズを変更してウィンドウのサイズ変更イベントをトリガーするか、コンポーネントを別の方法で再描画します。 this stackoverflow postを見ても、クロムではサポートされていませんが、代わりにwindow.matchMedia('print')を使用する方法が説明されています。

常に画面のサイズやサイズ変更イベントではなくCSSメディアクエリに依存するのが最善ですが、必ずしもそうではない場合もあります。

+0

このMarcのおかげで、私はそれが役に立ちました。 componentWillMount内のwindow.matchMedia( 'print')にリスナーを追加しました。これは、クエリが一致するかどうかによってstateの 'isPrinting'プロパティをtrueまたはfalseに変更し、forceUpdate()を呼び出します。ただし、forceUpdateによってトリガーされた再レンダリングは、印刷ダイアログが閉じるとメディアが再び変更された時点でのみ発生します。 –

+0

@ThomasHopkins、私が手伝ってくれて嬉しいです。ところで、これは素晴らしい解決策です。おそらく、他の人たちのコードを投稿して、それがどのように動作するかを見ることができます。 –

+1

@MarcGreenstockに感謝しますが、残念ながらこれは解決策ではありません。 forceUpdateで起こるはずの再レンダリングは、印刷ダイアログが閉じると実行されますが、それは遅すぎます。 –

1

コンポーネントでmatchMedia APIを使用する必要があります。しかし、それを自分自身でやってみると、あなたはホイール全体を再発明するでしょう。これを処理する既存のライブラリを使用する方が簡単です。 https://www.npmjs.com/package/react-responsiveをチェックしてください。これは、matchMedia以上のReactベースのラッパーコンポーネントを持っているので、プロジェクトで素早くプロトタイプを作成できるはずです。ポリフィルも利用可能です。私が考えることができる他の利点の1つは、インタフェースに印刷プレビューオプションを設定して、ギャラリーを印刷モードでどのように見えるかをプレビューできるようにすることです。このために、このライブラリのサーバーレンダリング機能を使用して印刷モードをシミュレートすることができます。

PS:私はこのプロジェクトに何ら関係していません。

3

使用メディアクエリーはまたWitVaultのソリューションを縦向きと横向きの印刷

@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

をターゲットに、私ははるかに簡単に複雑print.cssの取り扱いになりリアクト簡単なコンポーネントを作成しました。代わりに、すべてのマークアップ上のクラス、IDのなどを追加し、複雑なprint.cssファイルを作成する、次のようにあなたは私の反応-印刷ライブラリを使用することができます。

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

rootにこのIDを追加します(またはどこかに高いアップあなたのDOMツリー内の)あなたの現在のコンテンツの(しかし、内部のbodyタグ内)

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

は、「プリントマウント」のidを持つ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')); 

基本的に、これはあなたの印刷可能なバージョンをレンダリングし、それがされるまで隠されていますこれはスライディングギャラリーに必要な場合は、スライダの変更イベントにフックして、古いものをアンマウントして新しいものをマウントして、プリントテンプレートを再作成したいと思うでしょう。

希望これは役に立ちます!

関連する問題