学習記録

プログラミングの学習中に調べて解決したこと等の記録です。

スムーズスクロールをした後にスクロールが効かなくなり、ボタンが点滅する不具合を解消する方法

 

 

どのようなものを作ろうとしたか

縦長のホームページでよくある「ある程度までスクロールしたら横に出てくる、ページ先頭に戻れるボタンを実装しようとしたときのことでした。

 

どのような不具合が起きたか

このとき

1、ボタンを押してページ先頭まで戻ったあと、一定時間スクロールが出来なくなる

2、スクロールが効くようになった後、ボタンが急に出たり現れたり、点滅を繰り返す

という不具合が起きました。

そのときのコードは以下のようなものです。

 

html

<!-- 上へ戻るボタン -->
    <p class="totop js-totop">
      <a href="#top" class="totop__link">to top</a>
    </p>

 

jQuery

// 上に戻るボタンの外側
  var toTopBtn = $('.js-totop');

  // ボタンが現れる高さ
  var showBtnHeight = 500;

  // 上に戻る早さ0.05秒
  var DURATION = 500;

  $(window).scroll(function(){
    // スクロール量を取得してshowBtnHeight以上であれば
    if($(this).scrollTop() > showBtnHeight) {
      // ボタンを表示
      toTopBtn.fadeIn();
    }else{
   // ボタンを非表示
toTopBtn.fadeOut(); } // ボタンをクリックしたら上までスクロール toTopBtn.click(function(){ $('body,html').animate({ scrollTop: 0 }, DURATION); return false;

 

エラーの原因の予想

エラーの原因はそれぞれ

1、ボタンを押してページ先頭まで戻ったあと、一定時間スクロールが出来なくなる

→scrollTop: 0と記載したが、何かが邪魔をしスクロールが上まで行き切ってないと判断されているため、scrollTop: 0を満たそうとしてスクロールが出来なくなったのではないか。

 

2、スクロールが効くようになった後、ボタンが急に出たり現れたり、点滅を繰り返す

→ボタンの表示に関わる記載がtoTopBtn.fadeIn();とtoTopBtn.fadeOut();のため、記載が誤っているのではないか。

 

と予想しました。

 

 

エラーの原因と修正後のコード

予想に反して、原因は1つでした。

if(scrollTop >= posBottom) { ですが、
ページ下部にいったときにこの条件が複数回呼ばれています。
よって $('body').animate({scrollTop:0},2000); も複数回呼ばれます。
ページトップに移動した後も実際には呼ばれた回数実行されているので、その間はさらにスクロールしても scrollTop:0 に移動されているので、スクロールができないような状態になっています。

引用元:javascript - animate()で上端までスムーズスクロールしたあとにスクロールがしばらく効かなくなります。 - スタック・オーバーフロー

 

 

if文の判定はボタンが現れる消えるの境い目でのみ行われているのかと思いきや、スクロールに合わせて何度も行われていたため、ページトップに戻った後も

 

溜まっていたif文の判定の回数だけボタンが現れたり消えたりを繰り返し

$(window).scroll(function(){
    // スクロール量を取得してshowBtnHeight以上であれば
    if($(this).scrollTop() > showBtnHeight) {
      // ボタンを表示
      toTopBtn.fadeIn();
    }else{
      toTopBtn.fadeOut();
    }

 

この scrollTop: 0が何度も呼ばれていたため一定時間スクロールが効かなかった

$('body,html').animate({
        scrollTop: 0
      }, DURATION);

 

のだということがわかりました。 

 

記事を参考にstop()をつけ、上に戻った場合はあとに溜まっているアニメーションをすべてクリアにすることにより、どちらの不具合も解消させることができました。

 $('body,html').stop().animate({
        scrollTop: 0
      }, DURATION);

stop() - jQuery 日本語リファレンス

 

 

不具合を受けて

不具合が2つ起きたため原因は別々のところにあると思いきや、同じことが根底にあったというのにはとても驚きました。

複数の不具合が同時に発生したとしても慌てて一度に対処しようとするのではなく、冷静に1つずつ取り組んでいけば早期に解決できるため、1つ1つ確実に解消することを今後心がけていきます。