始めに
JavaScriptにはwindow.matchMedia
というものがあって、これを使うとブレークポイントの設定が簡単にできます。
ブレークポイントの設定
const breakpoint = window.matchMedia('(min-width:769px)');
console.log('isMatch:', breakpoint.matched);
// ブレークポイントが切り替わった時の判定
breakpoint.addListener(() => {
console.log('breakpoint changed.');
});
PC/SP個別の設定は切り替えの度にリセットしてから新しいメディア幅の設定をしないといけないのですが、これを手抜きしてリロードして設定をリセットしていました。ただこの設定をしたときに問題が起きました。
ブレークポイント切り替え時にリロードする
const breakpoint = window.matchMedia('(min-width:769px)');
// PC時の設定
if (breakpoint.matched) {
...
} else { // SP時の設定
...
}
// ブレークポイントが切り替わった時の判定
breakpoint.addListener(() => {
// 本来ならPCで設定したものをリセットしてSPの設定をするといった処理が必要だが、
// リロードすることで再設定のことを考えなくてよくなる
window.location.reload();
});
印刷時にメディアクエリの判定が行われる
Chromeで印刷プレビューがされるときに、ブレークポイントの判定が行われてリロードされてしまいました。PCからSPに変わったと判断されちゃった感じです。他のブラウザはちゃんと検証していませんが、とりあえずリロードはされてませんでした。
解決方法
とりあえず印刷中はこのブレークポイント判定をOFFにすることでリロードされるのを防ぐことができました。
印刷時はブレークポイント判定をOFFにする
// ブレークポイントを指定して、切り替わった時にリロードする
const breakpoint = window.matchMedia('(min-width:769px)');
const mediaPrint = window.matchMedia('print');
const onBreakpointChange = () => {
window.location.reload();
};
breakpoint.addListener(onBreakpointChange);
// 印刷のプレビューでもブレークポイントの判定がされて、Chromeだとリロードされてしまうので
// 印刷中はブレークポイントの切り替え監視をやめる
mediaPrint.addListener(() => {
if (mediaPrint.matches) {
breakpoint.removeListener(onBreakpointChange);
} else {
breakpoint.addListener(onBreakpointChange);
}
});
終わりに
JSの設定を手抜きしていたら思わぬところでバグに遭遇してしまいました。まさか印刷プレビュー画面にも判定されるとは思いもしませんでした(仮にあったとしてもブラウザ側の方に影響が出るとは思いませんでした)。
一応上記の方法で対応できたので、この辺でつまづいている人のお役に立てられたら幸いです。