📌
JSのレスポンシブ対応をresizeからmatchMediaに移行した
JS でブレークポイント毎に処理を分ける場合の方法を resize から matchMedia に移行したので、その際のメモ書きです。
昔ながらの方法
恥ずかしながら、最近まで JS でブレークポイント毎に JS 処理を切り替える場合、
以下のように昔ながらの resize イベントの監視を使っていました...
昔ながらの方法
/**
* イベントリスナー
*/
const listener = () => {
// リサイズ時に行う処理
if (window.innerWidth >= 768) {
// 768px以上
console.log('PC用ブレークポイント用処理');
} else {
// 768px未満
console.log('SP用ブレークポイント用処理');
}
};
// リスナー登録
window.addEventListener('resize', listener);
// 初期化処理
listener();
この方法は、リサイズの度にゴリゴリ listener 関数が実行されるので、できればやめたいと考えていました...💣
window.matchMedia をとりあえず使ってみた方法
以前、何かの記事で window.matchMedia を見かけたときは、以下のように CSS のメディアクエリと同じ記法で書けるので、いいなーぐらいの認識でした。
window.matchMediaをとりあえず使ってみた方法
/**
* イベントリスナー
*/
const listener = () => {
// リサイズ時に行う処理
if (window.matchMedia('(min-width: 768px)').matches) {
// 768px以上
console.log('PC用ブレークポイント用処理');
} else {
// 768px未満
console.log('SP用ブレークポイント用処理');
}
};
// リスナー登録
window.addEventListener('resize', listener);
// 初期化処理
listener();
これなら (orientation: portrait)
などデバイスの向きの判定もできますが、あんまりそういう複雑なメディアクエリ書く機会もなく、これなら別に置き換える意味も薄いなーと 😇
window.matchMedia をちゃんと使った方法
先日とある OSS の issue を見ているときに以下のようなwindow.matchMedia
の使い方を見つけました 💡
window.matchMediaをちゃんと使った方法
const mediaQueryList = window.matchMedia('(min-width: 768px)');
/**
* イベントリスナー
*/
const listener = (event) => {
// リサイズ時に行う処理
if (event.matches) {
// 768px以上
console.log('PC用ブレークポイント用処理');
} else {
// 768px未満
console.log('SP用ブレークポイント用処理');
}
};
// リスナー登録
// mediaQueryList.addListener(listener); // @deprecated
mediaQueryList.addEventListener("change", listener);
// 初期化処理
listener(mediaQueryList);
listener 関数が実行されるのは、ブレークポイントが切り替わったタイミングのだけなので、
resize の監視と比べて無駄に listener 関数が実行されなくなります 🤗🤗🤗
この使い方が MDN のサンプルに載っていないのかなと思っていたらmatchMedia
の戻り値のMediaQueryListのほうに書いてありました。。。
そこまでは、なかなか見ない...
Discussion
mediaQueryList.addListenerが非推奨なので、以下のように書き換えた方がよさそうです。
@hayato07
ありがとうございます。修正いたしました。
window.matchMediaをちゃんと使った方法の
const mediaQueryList = window.matchMedia("(max-width:767px)");
この箇所、min-widthではありませんか?間違っていたらすみません
コメントありがとうございます。
const mediaQueryList = window.matchMedia("(max-width:767px)");
maxもpxも間違っていたので修正しました!