【JavaScript】追従するトップに戻るボタンをフッターの手前で止める

どうも、くまだです。

画面下によく見かける追従するトップに戻るボタンを、フッターの手前で止める実装方法。よくあるやつです。

トップに戻るボタンをフッターの手前で止める実装方法

  <div class="conteiner">
    <header>ヘッダー</header>
    <main>
      <div class="fv"></div>
      <div class="contents">コンテンツ</div>
    </main>
    <footer>フッター</footer>

    <div class="back-to-top" id="page-top">
      <a href=""></a>
    </div>
  </div>
  
header {
  width: 100%;
  height: 60px;
  background-color: skyblue;
  position: fixed;
  top: 0;
  left: 0;
}
.conteiner {
  position: relative;
}
.fv {
  height: 700px;
  background-color: orange;
}

.contents {
  background-color: lightsalmon;
  height: 2000px;

}

.back-to-top {
  z-index: 100;
  position: fixed;
  right: 11px;
  bottom: 61px;
  width: 35px;
  height: 35px;
  border: 1px solid #ffffff;
  border-radius: 50%;
  background: red;
  cursor: pointer;
  transition: opacity .4s;
  opacity: 0;
}

.back-to-top a:before {
  position: absolute;
  width: 10px;
  height: 10px;
  transform: rotate(-45deg);
  border-top: solid 2px #ffffff;
  border-right: solid 2px #ffffff;
  content: "";
  transform: rotate(-45deg) translate(-17%, -50%);
  top: 50%;
  left: 50%;
}

footer {
  background-color: lightcyan;
  height: 300px;
}
document.addEventListener("DOMContentLoaded", function () {
  const pageTop = document.querySelector("#page-top");
  const scrollThreshold = 100;


  function scrollTop() {
    window.scroll({
      top: 0,
      behavior: "smooth",
    });
  }

  function scrollEvent() {
    if (window.scrollY > scrollThreshold) {
      pageTop.style.opacity = "1";
    } else {
      pageTop.style.opacity = "0";
    }
  }


  function Position() {
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollPosition = window.innerHeight + window.scrollY;
    const footHeight = document.querySelector("footer").offsetHeight;
  
    if (scrollHeight - scrollPosition <= footHeight) {
      pageTop.style.position = "absolute";
      pageTop.style.bottom = footHeight + "px";
      
    } else {
      pageTop.style.position = "fixed";
      pageTop.style.bottom = "0";
    }
  }

  pageTop.addEventListener("click", scrollTop);
  window.addEventListener("scroll", scrollEvent);
  window.addEventListener("scroll", Position);
});

初期状態ではトップに戻るボタンは非表示で、少しスクロールしたらふわっと表示。画面トップまで戻ると、トップに戻るボタンが非表示になり、下までスクロールすると、フッターの手前でトップに戻るボタンの追従が止まります。

トップに戻るボタン自体はCSSでスタイルします(本題はJSなのでCSS解説は省略)。

以下の部分で、トップに戻るボタンを取得し変数に格納。あと、いくらスクロールしたらトップに戻るボタンを表示させるのか、というのをscrollThresholdの変数で数字は適当に100に設定。

  const pagetop = document.querySelector("#page-top");
  const scrollThreshold = 100;

以下の部分で、ページトップに戻る関数。top:0でトップにスクロールする位置、behavior: “smooth”でスムーズなスクロールの設定。

  function scrollTop() {
    window.scroll({
      top: 0,
      behavior: "smooth",
    });
  }

スクロールによってトップに戻るボタンの表示、非表示は以下の部分。

  function scrollEvent() {
    if (window.scrollY > scrollThreshold) {
      pagetop.style.opacity = "1";
    } else {
      pagetop.style.opacity = "0";
    }
  }

現在のスクロール位置が、最初に設定したscrollThresholdよりも大きい場合とそうでない場合をif文で処理を分ける。

大きい場合は、pagetop.style.opacity = “1”;でトップに戻るボタンを表示。そうでない場合はpagetop.style.opacity = “0”;で非表示。

以下の部分で、ページ全体の高さ、現在のスクロール位置、フッターの高さを取得してそれぞれ変数に格納。

 // ページ全体の高さを取得
  const scrollHeight = document.documentElement.scrollHeight;
  // 現在のスクロール位置を取得
  const scrollPosition = window.innerHeight + window.scrollY;
  // フッター要素の高さを取得
  const footHeight = document.querySelector("footer").offsetHeight;

そして以下の部分で、フッターの直前までスクロールした場合とそうでない場合で処理をわけます。

  // スクロール位置がフッター手前に来た場合
  if (scrollHeight - scrollPosition <= footHeight) {
    // ページトップボタンの位置を絶対位置に
    pageTop.style.position = "absolute";
    pageTop.style.bottom = footHeight + "px";
  } else {
    // ページトップボタンの位置を固定位置に
    pageTop.style.position = "fixed";
    pageTop.style.bottom = "0";
  }

これらの処理を関数としてまとめる。

  function Position() {
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollPosition = window.innerHeight + window.scrollY;
    const footHeight = document.querySelector("footer").offsetHeight;

    if (scrollHeight - scrollPosition <= footHeight) {
      pageTop.style.position = "absolute";
      pageTop.style.bottom = footHeight + "px";

    } else {
      pageTop.style.position = "fixed";
      pageTop.style.bottom = "0";
    }
  }

あとはそれぞれイベントを以下の部分で登録。

  pagetop.addEventListener("click", scrollTop);
  window.addEventListener("scroll", scrollEvent);
  window.addEventListener("scroll", Position);

以上。

ここまで読んでくださりありがとうございました。

この記事を書いた人