29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

un-T factory! XAAdvent Calendar 2019

Day 10

window.matchMediaによる、メディアクエリに応じたJavaScriptの実行

Posted at

はじめに

レスポンシブデザインのWebページを制作する際、CSSのメディアクエリで指定した条件(ブラウザ幅などのブレークポイント)に応じてJavaScriptの処理を実行させたい場面があります。

ブラウザ幅の変化を扱う場合、古くは「windowresize イベントを監視してブラウザ幅を取得する」といった手法も取られていましたが、パフォーマンスなどを考慮した場合には少し実装に工夫が必要でした。

IE10以降の主要なブラウザであれば window.matchMedia メソッド を利用することでシンプルな実装が可能です。

window.matchMedia メソッドを利用した実装

例として、ブラウザ幅 769px をブレークポイントとする場合を考えると、JavaScriptのコードは次のようになります。

JavaScript
// 1. 変数mqlにMediaQueryListを格納
const mql = window.matchMedia('(min-width: 769px)');

// 2. メディアクエリに応じて実行したい処理を関数として定義
const handleMediaQuery = function(mql) {
  if (mql.matches) {
    // 769px以上の場合の処理
    console.log('769px以上');
  } else {
    // 769px未満の場合の処理
    console.log('769px未満');
  }
};

// 3. イベントリスナーを追加(メディアクエリの条件一致を監視)
mql.addListener(handleMediaQuery);

// 4. 初回チェックのため関数を一度実行
handleMediaQuery(mql);

大きく4つの処理に分かれているので、1つずつ内容を追ってみます。

1. 変数mqlにMediaQueryListを格納

const mql = window.matchMedia('(min-width: 769px)');

console.log(mql); // MediaQueryList {media: "(min-width: 769px)", matches: true, ...}

まず、Webページ上で利用したいメディアクエリを引数として window.matchMedia メソッドを実行します。
window.matchMedia メソッドの実行により MediaQueryList オブジェクトが生成されるので、それを変数 mql に格納しています。

MediaQueryList オブジェクトは matches というプロパティを持っており、メディアクエリに一致した条件下では true が、一致しない条件下では false が格納されます。

2. メディアクエリに応じて実行したい処理を関数として定義

const handleMediaQuery = function(mql) {
  if (mql.matches) {
    // 769px以上の場合の処理
    console.log('769px以上');
  } else {
    // 769px未満の場合の処理
    console.log('769px未満');
  }
};

ここでは handleMediaQuery という関数を定義し、前述した matches プロパティの値(true or false)によって実行したい処理を書き分けています。

3. イベントリスナーを追加(メディアクエリの条件一致を監視)

mql.addListener(handleMediaQuery);

MediaQueryList オブジェクトの addListener メソッドでイベントリスナーを設定できます。
MediaQueryList.matches が変化するタイミング(今回の例ではブラウザ幅が769pxを越えるタイミング)で、引数に指定した handleMediaQuery 関数が実行されます。

4. 初回チェックのため関数を一度実行

handleMediaQuery(mql);

Webページの初期状態でメディアクエリに応じた処理をおこなうため、一度 handleMediaQuery 関数を実行しています。

ここまでのJavaScriptコードを実行すると、ブラウザ幅に応じてコンソールに 769px以上 / 769px未満 というメッセージが表示されることを確認できるかと思います。

ブレークポイントの通過をカスタムイベントとして扱う

メディアクエリの条件一致チェックの際に カスタムイベント を発生させておくことで、ブレークポイントの通過(例えばPCビューとモバイルビューの切り替え)をWebページ上での一つのイベントとして取り扱うことができます。
カスタムイベントの利用にはjQueryの trigger / on メソッドが便利です。

jQueryでカスタムイベントを利用する(.on() と .trigger())

const mql = window.matchMedia('(min-width: 769px)');

const handleMediaQuery = function(mql) {
  // カスタムイベント 'breakpoint-{type}' を発火
  if (mql.matches) {
    $(window).trigger('breakpoint-large');
  } else {
    $(window).trigger('breakpoint-small');
  }
};

mql.addListener(handleMediaQuery);
handleMediaQuery(mql);
function doSomething() {
  $(window).on('breakpoint-large', function() {
    // 769px以上の場合の処理
    console.log('769px以上');
  });

  $(window).on('breakpoint-small', function() {
    // 769px未満の場合の処理
    console.log('769px未満');
  });
}

doSomething();

上記の例では、doSomething 関数内でカスタムイベントを利用し、ブラウザ幅に応じた処理を実行しています。

参考リンク

Can I use... matchMedia
window.matchMedia - Web API | MDN
MediaQueryList - Web API | MDN

29
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?