jQueryのrizeは画面サイズが変わるたびに実行するので、ブラウザを小さくするときなどは連続で動作してしまいよろしくありません。
一回きり実行という方法もある様ですが、それはそれで柔軟性を欠いてしまいます。なにかいい方法はないものかと彷徨っていたら下記の記事を見つけました。
JSのレスポンシブ対応をresizeからmatchMediaに移行した
株式会社ナンバーフォー
これぞわたくしが探し求めていた方法でした。要件はこんな感じ。
- 特定の要素が画面外に出たらヘッダーを固定表示、画面内に戻ってきららヘッダー固定解除。ただし画面サイズが1024px以下の場合はヘッダー固定表示しない。
- 画面サイズが1024px以下の場合はslickを有効にしてスライダー表示させる。1024以上の場合はslickを無効化しスライダー表示させない。
で、出来上がったのがこちら。
const mediaQueryList = window.matchMedia('(min-width: 1024px)');
const listener = (event) => {
// リサイズ時に行う処理
if (event.matches) {
// 1024px以上
var scroll;
var objH = $('header').outerHeight();
var objTop = $('header').offset().top;
var objBottom = objTop + objH;
$(window).on('scroll', function(){
scroll = $(window).scrollTop();
if(scroll >= objBottom){
//要素が画面外に出たら処理
$('.header-contents').addClass('bar-display');
} else {
//要素が画面内に入ってきたら処理
$('.header-contents').removeClass('bar-display');
}
});
//PCサイズの場合、slick無効
$('.slider').slick('unslick');
} else {
// 1024px未満
//イベントを実行しない(無効化)
$(window).off('scroll');
//bar-displayが設定されていたら削除
$('.header-contents').removeClass('bar-display');
// スマートフォンの場合 slick有効
$('.slider').slick({
//slickの設定を書く
});
}
};
// リスナー登録
mediaQueryList.addEventListener("change", listener);
// 初期化処理
listener(mediaQueryList);
不具合発生
これで完成めでたしめでたしと行きたいところでしたが、時折ハンバーガーメニューが動作しなくて原因を調べたところ「Cannot read property 'unslick' of undefined」ってエラーを吐いていました。
これのせいで止まってしまっていたようです。解決方法を検索し、こちらの記事を参考に修正しました。
slickのCannot read property 'unslick' of undefinedエラーを直す方法
てざなり
動作を停止するunslickと動作オプションの個所を書き換えました。
//修正前
$('.slider').slick('unslick');
//修正後
$('.slider.slick-initialized').slick('unslick');
//修正前
$('.slider').slick({
//オプション
});
//修正後
$('.slider').not('.slick-initialized').slick({
//オプション
});
修正版
エラーが発生したしなかったりでよくわかりませんが、とりあえずエラーは発生しなくなりました。
.slick-initializedクラスを調整して対応するするということは、初期化時にたまに失敗するのでしょうか?
const mediaQueryList = window.matchMedia('(min-width: 1024px)');
const listener = (event) => {
// リサイズ時に行う処理
if (event.matches) {
// 1024px以上
var scroll;
var objH = $('header').outerHeight();
var objTop = $('header').offset().top;
var objBottom = objTop + objH;
$(window).on('scroll', function(){
scroll = $(window).scrollTop();
if(scroll >= objBottom){
//要素が画面外に出たら処理
$('.header-contents').addClass('bar-display');
} else {
//要素が画面内に入ってきたら処理
$('.header-contents').removeClass('bar-display');
}
});
//PCサイズの場合、slick無効
$('.slider.slick-initialized').slick('unslick');
} else {
// 1024px未満
//イベントを実行しない(無効化)
$(window).off('scroll');
//bar-displayが設定されていたら削除
$('.header-contents').removeClass('bar-display');
// スマートフォンの場合 slick有効
$('.slider').not('.slick-initialized').slick({
//slickの設定を書く
});
}
};
// リスナー登録
mediaQueryList.addEventListener("change", listener);
// 初期化処理
listener(mediaQueryList);