メディアクエリと言えばCSSでよく使います。今回はヘッダーを固定させたので、コンテンツが隠れてしまうのを防ぐ為にヘッダーの高さ分の余白をブレイクポイント事に取得する必要がありました。
よくwindow
の resize
イベントでブラウザ幅を監視してwindow.innerWidth
で幅を取得するやり方がありました。
しかしメディアクエリに設定したブレイクポイントをJavaScriptで検知するメソッドがあるので今回はそちらを試してみました。
目次
window.matchMediaとは?
では、どうしたらブレイクポイントを検知できるのかというと、window.matchMediaというメソッドがあります。
指定された メディアクエリ文字列のパース結果を表す、新しい
https://developer.mozilla.org/ja/docs/Web/API/Window/matchMediaMediaQueryList
オブジェクトを返します。
基本となるコード
まずは基本となるソースコードを載せます。いろいろサイト見ましたが、ほぼほぼ決まり文句のように同じです。
var mediaQuery = window.matchMedia("(max-width: 896px)");
// ウィンドウサイズが変更されても実行されるように
mediaQuery.addListener(handle);
function handle(mq) {
if (mq.matches) {
// ウィンドウサイズが896px以下の時の処理
} else {
// それ以外の時の処理
}
}
// ページが読み込まれた時に実行
handle(mediaQuery);
window.matchMediaでブレイクポイントを指定する
window
オブジェクトのmatchMedia
メソッドの引数に検知したいブレイクポイントを指定する。戻り値はMediaQueryList
のオブジェクトになります。
中身を知りたい場合はconsole.log
で以下の値を得られます。
MediaQueryList { media: "(min-width: 896px)", matches: true }
検知できるようにイベントリスナーを設定する。
レスポンシブでウィンドウサイズを変更してブレイクポイントを常に検知できるようにMediaQueryList
にaddListener
でイベントリスナーを登録することができます。今回はhandle
関数を指定しています。
関数内で条件分岐する
handle
関数では、MediaQueryList
オブジェクトを引数として渡します。MediaQueryList
オブジェクトにはmatches
プロパティがあり、true
/ false
の論理値が取得できるのでそれをもとにif
文で条件分岐で処理します。
if (mq.matches) {
// ウィンドウサイズが896px以下の時の処理
} else {
// それ以外の時の処理
}
ページが読み込まれた時に実行
イベントリスナーと関数内の処理をしても読み込み時には実行されないと困るので、一度関数を実行します。
その際にhandle
関数内にmatchMedia
で取得したMediaQueryList
オブジェクトを引数として渡しておきましょう。
// ページが読み込まれた時に実行
handle(mediaQuery);
複数のメディアクエリを条件分岐したい場合は?
こうなると複数のメディアクエリのブレイクポイントをもとに条件分岐したいと思いますよね。これまでの方法だと1つのメディアクエリだけになります。
複数の場合は以下の方法があります。
if (window.matchMedia('(min-width: 980px)').matches) {
//処理
} else if (window.matchMedia('(min-width: 481px)').matches) {
//処理
} else if (window.matchMedia('(min-width: 360px)').matches) {
//処理
}
だたこの方法だとページが読み込まれた時にしかチェックできません。
複数のメディアクエリで条件分岐させるには?
では、どのように複数のメディアクエリをブレイクポイントして条件分岐させるのかというと以下の方法となります。
function checkMediaQuery(){
if (window.matchMedia('(min-width: 980px)').matches) {
//処理
} else if (window.matchMedia('(min-width: 481px)').matches) {
//処理
} else if (window.matchMedia('(min-width: 360px)').matches) {
//処理
}
}
//読み込み時とリサイズ時に関数を実行
window.onload = checkMediaQuery;
window.onresize = checkMediaQuery;
if文でメディアクエリ事に条件分岐した処理を関数にして、読み込み時にwindow.onload
ウィンドウ幅のサイズが変更された時にwindow.resize
で関数を実行しています。
結局はwindow.resize
を使うことになりましたが、ブレイクポイントの時にしか処理が動くのでCSSのメディアクエリと同じタイミングで何かしたい時はいいかもですね。
まとめ
さて、今回は、window.matchMedia
というメソッドがあることを今更知ったのでメモしました。
一応codePenでサンプルを2つ作ってみました。以下、codePenを別タブで開くなりしてウィンドウ幅を変えてみるとブレイクポイントで背景色が変わります。