1
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ウィンドウサイズ変更時に一度だけjQueryを実行

Posted at

問題提起

レスポンシブデザインをつくりましたが、ウィンドウサイズを変えると、jQueryが意図せず発火したり、されなかったり……という問題が発生しました。

以下が正解の挙動です。
Image from Gyazo

以下が問題の挙動です。
Image from Gyazo

Image from Gyazo

正解では、ウィンドウサイズが大きい時には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終了時に画面が一度だけリロードされるようになります。

1
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?