【JavaScript】印刷のイベント – beforeprint / afterprint

誰しもウェブページを印刷することはあるのではないでしょうか。ウェブサイト制作において印刷を意識するとしたら、メディアクエリを使って印刷用のスタイルを用意することでしょうか。しかし、JavaScript においても印刷に関連するイベントが用意されています。今回は、beforeprint イベントと afterprint イベントについて紹介します。

イベントの説明

beforeprint イベントと afterprint イベントは window オブジェクトで発生します。これらのイベントを初めて知った人は、おそらく beforeprint イベントはページ印刷の直前に、afterprint イベントはページ印刷が完了した直後に発生すると思ったのではないでしょうか。実はそうではありません。

近年のメジャーなブラウザーでは、ページを印刷しようとすると印刷プレビュー画面が開きますが、このタイミングで beforeprint イベントが発生します。

そして、印刷プレビュー画面を閉じると afterprint イベントが発生します。残念なことに、afterprint イベントから、印刷が開始されたのかキャンセルされたのかは判別できません。afterprint イベントは単に印刷プレビュー画面が閉じられたということしか判別できません。このあたり、イベントの名前からの期待を裏切られた感じもしますね。

ブラウザーの実装状況

Chrome、Edge、Firefox、Safari のいずれも、beforeprint イベントと afterprint イベントをサポートしています。しかし私が試した限り、Firefox だけは afterprint イベントの挙動が期待通りではありませんでした。

Firefox の場合、印刷プレビュー画面が開いた時点で、beforeprint イベントと afterprint イベントの両方が発生してしまいます。そして、印刷プレビュー画面が閉じた時点では何も発生しません。しかし、後述する利用シーンにおいては問題になりません。それについては後述します。

サンプルコード

次のコードは button 要素のボタンを押すと、印刷プレビュー画面を表示します。並行して、beforeprint イベントと afterprint イベントの受信をコンソールに出力します。

<button type="button" id="prt-btn">Print</button>
document.querySelector('#prt-btn').addEventListener('click', () => {
  window.print();
}, false);

window.addEventListener('beforeprint', (event) => {
  console.log(event.type);
}, false);

window.addEventListener('afterprint', (event) => {
  console.log(event.type);
}, false);

このサンプルでは addEventListener() メソッドでイベントをキャッチしましたが、これらのイベントは次のようにイベントハンドラ onbeforeprintonafterprint でもキャッチできます。

window.onbeforeprint = (event) => {
  console.log(event.type);
};

window.onafterprint = (event) => {
  console.log(event.type);
};

使いどころ

印刷用のレイアウトやスタイリングは今やメディアクエリが主流だと思いますが、もし CSS で制御しきれない、または、やりにくい場合は、JavaScript を使って一時的に DOM を操作することもできます。あまり良い例ではありませんが、次のコードは、class 属性の値に advertisement が含まれるブロックを非表示にしてから印刷プレビュー画面を表示します。そして、印刷プレビュー画面が閉じられたら、非表示にしたブロックを元に戻します。

<div class="advertisement">
  広告です
</div>

<button type="button" id="prt-btn">Print</button>
document.querySelector('#prt-btn').addEventListener('click', () => {
  window.print();
}, false);

const toggleAdBlocks = (event) => {
  const hidden = (event.type === 'beforeprint') ? true : false;
  const ad_block_list = document.querySelectorAll('.advertisement');
  for (let i = 0; i < ad_block_list.length; i++) {
    ad_block_list.item(i).hidden = hidden;
  }
}

window.addEventListener('beforeprint', toggleAdBlocks, false);
window.addEventListener('afterprint', toggleAdBlocks, false);

前述の通り、Firefox では印刷プレビュー画面が表示された時点で beforeprint イベントだけでなく afterprint イベントも発生してしまいます。一見これでは全く意味がないように思ってしまいますが、実はこのサンプルのケースにおいては Firefox でも問題なく機能します。

Firefox では afterprint イベントの意味が他のブラウザーとは少し異なるようです。Firefox の場合、印刷プレビュー画面の表示・非表示がイベントのトリガーではなく、印刷イメージの生成がトリガーのようです。

まとめ

実のところ、私自身、印刷機能を実サイトで実装したことはありません。おそらく皆さんもウェブサイト構築にて印刷機能を実装することはないのではないでしょうか。しかし、万が一の時にでも、この記事が参考になれば幸いです。

今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。

Share