📌

JSのレスポンシブ対応をresizeからmatchMediaに移行した

2021/03/13に公開
4

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のほうに書いてありました。。。
そこまでは、なかなか見ない...

GitHubで編集を提案
株式会社ナンバーフォー

Discussion

hayato07hayato07

mediaQueryList.addListenerが非推奨なので、以下のように書き換えた方がよさそうです。

- mediaQueryList.addListener(listener);
+ mediaQueryList.addEventListener("change", listener);
ぬめちゃぬめちゃ

window.matchMediaをちゃんと使った方法の
const mediaQueryList = window.matchMedia("(max-width:767px)");

この箇所、min-widthではありませんか?間違っていたらすみません

らんす🍐らんす🍐

コメントありがとうございます。
const mediaQueryList = window.matchMedia("(max-width:767px)");
maxもpxも間違っていたので修正しました!