特定の画面幅を基準に処理を分ける方法を3つ紹介します
Window resize event を利用する
まず紹介するのは Window resize event を使った方法です。 Window: resize event - Web APIs | MDN
DEMO
実行頻度に注意する
最も古くから利用されてきた方法で、どのブラウザでも動かすことができます。
EventTarget.addEventListener()
を使って Window resize event に関数を紐付けます。
ウィンドウのサイズが変更する度に関数を実行して「今のウィンドウサイズ」を window.innerWidth
などで取得して処理を実行します。
window.addEventListener('resize', () =>{ el.innerHTML = window.innerWidth > 1000 ? '1000px 以上' : '1000px 未満'; });
実際に実務で利用する際にはそのまま関数を紐付けることはないでしょう。 throttle
や debounce
といった手法を使い、一定時間中1回だけ実行するようにしたり、一定時間後に 1回だけ実行するようにして処理を間引くことで過剰に実行されるのを制限します。
次項でその方法を紹介します。
Window resize event + throttleを利用する
上記であげたように、resize イベントに直接ハンドラーを紐付けると過剰に実行されていまいます。 実行回数を制限するために throttle を使って実行回数を制限してみます。
DEMO
throttle
処理は自作してもよいですが、ユーティリティライブラリ lodash) や throttle-debounce というシンプルなモジュールが公開されているのでこれを活用してしまうのが楽でよいでしょう。
今回は throttle-debounce
を使った例を示します。
throttle-debounce - npm
throttle()
の第一引数には処理を間引く時間を指定します。
ここで指定した時間内に複数回実行されても1度だけしか実行されなくなります。
const checkWidth = throttle(10, () => { el.innerHTML = window.innerWidth > 1000 ? '1000px 以上' : '1000px 未満'; }); window.addEventListener("resize", checkWidth);
Resize Observer を利用する
ResizeObserver - Web API | MDN HTML要素を監視して何かする Observer 系 API の一つ HTML要素のサイズを監視することができます。 html や body 要素を監視することで上の方法と同じようなことができます。
DEMO
const resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { el.innerText = entry.contentRect.width >= 1000 ? '1000px 以上' : '1000px 未満'; } }); resizeObserver.observe(document.querySelector('html'));
new ResizeObserver
で第一引数にリサイズ時のコールバック関数を指定してインスタンスを作成し、resizeObserver.observe
で DOM を指定します。
コールバック関数では ResizeObserverEntry
の配列を受け取れます。
ResizeObserverEntry
には 以下のような値が含まれています。
borderBoxSize
... border を含めたコンテンツのサイズ (inlineSize が横幅, blockSize が縦幅のよう)contentBoxSize
... border, padding を含めいないコンテンツのサイズcontentRect
... コンテンツの矩形情報を取得するdevicePixelContentBoxSize
... 実 pixel のコンテンツのサイズ(Retina Display だったら 2倍になる)
Resize Observer は比較的新しいAPIのため IE11 では使うことができません。 IE11 で動かしたい場合は polyfill を適用することで使うことができます。
resize-observer-polyfill - npm
また、こちらで画面幅を監視する場合、 resize event と実行タイミングは同じなので、 resize event と同様に実行回数を間引く処理を加えたほうがよいでしょう。
mediaQueryList を利用する
最後に、 mediaQueryList
を使った方法を紹介します。
DEMO
window.matchMedia.matches
を利用すると第一引数で渡したメディアクエリ文字列に一致するかどうかを真偽値で返してくれます。
const mediaQueryList = window.matchMedia('(min-width: 1000px)'); if(mediaQueryList.matches) { /* ビューポートの幅が 1000 ピクセル以上の場合 */ }
window.matchMedia
で作成される mediaQueryList
は addEventListener
を持っていて、
change
イベントを購読することでメディアクエリ文字列に一致したときの処理をコールバック関数に書くことができます。
const mediaQueryList = window.matchMedia('(min-width: 1000px)'); mediaQueryList.addEventListener('change', (event) => { console.log(event.matches ? 'マッチした!' : 'マッチしてない!'); }, false);
先述で挙げた2つの方法は画面のリサイズに対して反応するため、判定基準となる幅以外の時や縦のリサイズにも反応していました。
mediaQueryList
を使った方法なら境界値をまたいだ時だけ処理を実行することが可能です。
こちらは今のメジャーブラウザなら問題なく使うことができるようになっています。
但し MediaQueryList.addEventListener
は元々 mediaQueryList.addListener
という名前で実装されていた経緯から、現時点で IE や Safari などでは MediaQueryList.addListener
しか実装されていないため、これらのブラウザで利用する場合は MediaQueryList.addEventListener
の存在チェックを行った上でどちらのメソッドを利用するか決める必要があります。
MediaQueryList.addListener() - Web APIs | MDN