問題提起
レスポンシブデザインをつくりましたが、ウィンドウサイズを変えると、jQueryが意図せず発火したり、されなかったり……という問題が発生しました。
正解では、ウィンドウサイズが大きい時にはjQuery(アコーディオン)を機能させず、ウィンドウサイズが小さい時にjQuery(アコーディオン)を発火させています。
しかし問題の例では、ウィンドウサイズを変えても、初めのウィンドウサイズが適応されてしまっています。
コードはこちらです
if (window.matchMedia( '(max-width: 766px)' ).matches){
$(".title").on("click", function(){
$(this).next(".element").slideToggle(200);
});
$(document).on("click", ".element__parent", function(){
$(this).next(".element__child").slideToggle(200);
});
};
ifの条件が最初のウィンドウサイズにしか適応されないのが問題でした。
つまり、最初のウィンドウサイズが766px以上ならjQueryが機能せず、766px以下ならたとえウィンドウサイズを大きくしてもjQueryが適応されてしまします。
解決策
正解コードがこちらです
$(function(){
var timer = false;
$(window).resize(function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
location.reload();
}, 200);
});
if (window.matchMedia( '(max-width: 766px)' ).matches){
$(".title").on("click", function(){
$(this).next(".element").slideToggle(200);
});
$(document).on("click", ".element__parent", function(){
$(this).next(".element__child").slideToggle(200);
});
};
});
ウィンドウサイズを変化させるごとに画面をリロードするコードを足しました。
コードの説明
var timer = false;
$(window).resize(function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
location.reload();
}, 200);
});
細かいところの説明
・resize()
ウィンドウサイズが変わるごとにイベントを通知
・setTimeout()
一定時間経過後に処理を一回だけ実行する
・clearTimeout
setTimeout()でセットしたタイマーを解除する
・location.reload()
ページをリロード(再読み込み)する
全体の流れ
まず変数timerをfalseに設定
ウィンドウがresizeされ続けると以下が繰り返される。
・setTimeout()でセットしたタイマーを解除する
・0.2秒後にリロード
・setTimeout()でセットしたタイマーを解除する
・0.2秒後にリロード
・setTimeout()でセットしたタイマーを解除する
・0.2秒後にリロード
・・・
resizeが止まれば最後の「0.2秒後にリロード」が残るので、結果、resize終了時にリロードが一回される。
リロードがされた時のウィンドウサイズによって
if (window.matchMedia( '(max-width: 766px)' ).matches){
$(".title").on("click", function(){
$(this).next(".element").slideToggle(200);
});
$(document).on("click", ".element__parent", function(){
$(this).next(".element__child").slideToggle(200);
});
};
の実行が決まるので、結果、ウィンドウサイズを変えたところでjQueryを適応するか否かを判断される。
まとめ
ややこしい話になりましたが、要は
var timer = false;
$(window).resize(function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
location.reload();
}, 200);
});
のコードを入れれば、resize終了時に画面が一度だけリロードされるようになります。