JavaScript
jQuery

レスポンシブデザインで、PCデバイスとSPデバイスで処理を切り替える時のjQueryの書き方

More than 1 year has passed since last update.


課題

今日は乃木坂関係ないです。(さすがに絡められません..笑)

さて、いつもレスポンシブの案件制作してて、ハンバーガーメニューを実装することがよくあるんですね。

よくあるデザインが、PCの時にはヘッダーにリンクが横並びに並んでて、

SPのときはそのリンクがハンバーガーメニュー内に全部収納されるパターン。

で、あとで文言修正とかきたら面倒臭いから、コード出し分けはせず、

ulタグで作って、SPのときはそいつをslideToggleさせるみたいな処理を実装しています。

で、こういう時以下のような問題が生じます。

PCで見ている時、SPのウインドウ幅にします。

そして、ハンバーガーを開いて、閉じます。

次に、PCのウインドウ幅に戻すと、なんとナビが全部消えているんですよ。怖いなー怖いなー

当然です。slideToggle一回発動させちゃうと、ハンバーガー閉じるとdisplay: none;が付与されてしまいますから。

この例に限らず、こういった問題はよく生じると思います。

そこで、次のようなコードを書いて見たんですね。


解決法1(失敗ケース)

$(function(){

$('window').on('resize',function(){
var windowWidth = $('window').width();
if (windowWidth >= //SPのブレークポイント ) {
//SPの処理
} else {
//PCの処理
}
}).trigger('resize');
});

以上のような書き方をしたのですが、

こうしたらリサイズするたびに処理が走ってしまいます。

うーん、困った。

私が実現したいのは、

「ブレークポイントを通過した時のみに処理を実行する」ことです。

つまり、いくらリサイズしたって、

①PCからSPに切り替わるとき

②SPからPCに切り替わるとき

以上の2回だけ処理が走っていればよいのです。

よって以下のような記述になりました。


解決法2(成功ケース)

$(function(){

var lastWW = $('window').width();

if (lastWW <= //ブレークポイント) {
//SPの処理
} else {
//PCの処理
}

$('window').on('resize', function() {
var currentWW = $('window').width();

if (lastWW <= //ブレークポイント && //ブレークポイント < currentWW) {
//PCの処理
} else if (currentWW <= //ブレークポイント && //ブレークポイント < lastWW) {
//SPの処理
}

lastWW = currentWW;
});
});

上記のようになりました。

肝はlastWW = currentWWのところだと思っていて、

要は最後に処理が走ったときのデバイス幅を変数lastWWに保存しておくことってことですね。

この書き方で結構汎用的に利用しております。


まとめ

そもそもユーザーエージェント切り替えならばこんなのいらないのですが、

まだまだmedia queryで切り替える案件が大半だったので、よく使います。

もっとよいやり方あればご教示くださいませ。

というか、一回SP幅にして、そしてPC幅に戻してサイトを閲覧するエキセントリックなユーザーいるの?