[JavaScript] matchMediaでPCとSPの処理を分岐する
posted : 2022.08.11
こんにちは、ma-ya’s CREATE[まーやずくりえいと]です。
PCとSPでJSの処理を分けたい時ありますよね。
そんなときに便利なのがwindow.matchMediaですが、毎回何らかの記事をググってる気がするので、備忘録もかねて(ついでに注意点も添えて)記事にしときます。
PCとSPの処理を分けて実行するwindow.matchMediaサンプル
まずは雛形となるコード。
こんな感じで書いてやると、画面サイズが設定したブレイクポイントを通過したタイミングでのみ、処理を発火させることができます。
昔ながらだと resize イベントを使ってたらしいですが、それだとちょっとでも画面サイズが変わるだけで毎回処理が走ってしまうので、
scrollイベント同様パフォーマンス的にあまりよくないです。
//あんまりパフォーマンスが良くない window.addEventListener('resize', listener);
と、ここまでが雛形のお話。
ここからは実際にwindow.matchMediaを使う際の注意点です。
分岐内でaddEventListenerする際のポイント
実務でいざ使おうとしてハマりがちなのが(ぼくだけ…?)、PCとSPでの分岐内でaddEventListenerする時です。
語るより見た方がわかりやすいと思うので、今度は↓のサンプルをご覧ください。
※PCでの閲覧推奨
See the Pen
matchMedia example by mycreatesite (@mycreatesite)
on CodePen.
ここではブレイクポイントを通過した際、下記を実装することを想定してます。
- 画面がPC、SPサイズにそれぞれ切り替わったらconsole.log
- 画面がPCサイズでのみボタンクリックでalertさせる(イベントを発火する)
listener関数にはなるべく別途関数化した関数名を渡す
コードを見るとわかりますが、分岐内のaddEventListenerに渡すlistener関数には別途関数化したsampleFuncPCという関数名を渡してます。
これが一つ目のポイントです(と個人的には思ってます)。
ここに無名関数をよくやる感じで突っ込んでしまうと、複数回ブレイクポイントを跨いだ場合(画面を拡げたり縮めたりを繰り返した場合)、
同じ回数だけリスナが登録されてしまいます。
今回のサンプルで言うと、100回PC側にブレイクポイントを跨いだ場合は100回同じイベント処理が走ってしまうということです。
どうも無名関数だと毎回別のイベントと判定され、ブレイクポイントを跨ぐ度に同じイベントが要素に追加されてしまう模様。
加えて、あまりコードが長くなると全体の見通しも悪くなるので、ぼくはなるべくlistener関数には無名関数を渡さない(=別途関数化した関数名を渡す)ようにしてます。
分岐の片方だけで処理を行いたい場合、他方の処理ではremoveEventListenerする
上記のサンプルではSP側の処理でsampleFuncPCをremoveEventListenerしてます。
よくよく考えてみるとわかるんですが、window.matchMediaで処理を分岐したとしても、PC側で一度登録されたイベントがSP側で消えるわけではありません。
つまりPC側で一度ページを開いて、画面サイズを縮小してSPサイズにしたときも、PC側で一度登録されたイベントは発火してしまいます。
(それじゃ意味ねえじゃねえか!と感じる人もいるかもしれませんが…ぼくです)
なので分岐の片方だけで処理を行いたい場合、他方の処理ではremoveEventListenerするのが良いかなと個人的には思っています。
この時もlistener関数を無名関数で書いていると、普通にremoveEventListener出来ずにややこしくなるので、
その点でもなるべくlistener関数には無名関数を渡さないのが吉と自分は思っています。
[補足]画面サイズをグイグイ動かさないんだったら全部気にしなくてOK(かも)
ここまで書いといてアレですが、↑の話は画面サイズを拡げたり縮めたりグイグイ動かすことが前提の話とも言えます。
ページを読み込んだ後、特に画面サイズを変えないんだったら正直気にするだけ時間の無駄かもしれません苦笑
まあ、基本的には酔っ払ったオッサンの戯言なので適宜無視していただければよろしいです。
というわけで今回はwindow.matchMediaでPCとSPの処理を分岐するをテーマに備忘録を書いてみました。
どなたかの参考になればこれ幸い。
ではでは。