上毛印刷株式会社

【JavaScript】フッター表示域に入ったら、ページトップボタンを固定する

【JavaScript】フッター表示域に入ったら、ページトップボタンを固定する

2024年04月22日
WEBサイト制作
  • #HTML
  • #css
  • #JavaScript
  • #tips

こんにちは!
上毛印刷WEB制作担当のソーヤです。

今回はWEBサイトにほぼ必須といっていいページトップへ戻るボタンのtipsを紹介します!

今回の実装例は少し特殊なので、デモページを作成しました。
アクセスしてみてください。
デモページはこちら(別タブで開きます)

HTML例

<footer>
  <div class="l-container">
    <div class="c-footer">
      <div class="c-footerInner">
        <h1>
          <a href="/"><img src="./logo.png" alt=""></a>
        </h1>
        <div class="c-footerLink">
          <ul>
            <li><a href="#">著作権について</a></li>
            <li><a href="#" class="c-blank" target="_blank">プライバシーポリシー</a></li>
            <li><a href="#">サイトマップ</a></li>
          </ul>
          <small>
            <p>Copyright © jomo printing All Rights Reserved.</p>
          </small>
        </div>
      </div>
    </div>
  </div>
  <div class="c-pagetop" id="js-pagetop"><a href="#" class="">pagetop</a></div>
</footer>

CSS例

#js-pagetop {
  z-index: 100;
  transition: .4s;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  right: 90px;
  bottom: 20px;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background-color: #fff;
  border: 3px solid #000;
  text-indent: -9999px;
}
#js-pagetop.is-show{
  opacity: 1;
  pointer-events: auto;
}
#js-pagetop.is-pagetop {
  position: absolute;
  top: -50px;
  bottom: auto;
}
#js-pagetop a {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
}
#js-pagetop a::after{
  position: absolute;
	top: 13px;
	bottom: 0;
	left: 34px;
	margin: auto;
	content: "";
	vertical-align: middle;
	width: 20px;
	height: 20px;
	border-top: 2px solid #000;
	border-right: 2px solid #000;
  transform: rotate(-45deg);
}
.contents{
  text-align: center;
}
footer {
  position: relative;
  padding: 80px 0;
  background-color: #111;
}
.c-footer h1 {
  width: 250px;
}
.c-footer h1 img {
  width: 100%;
  max-width: 100%;
}
.c-footer small {
  color: #fff;
}
.c-footerInner {
  display: -webkit-flex;
  display: -ms-flex;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
}
.c-footerLink {
  justify-content: flex-end;
  margin: 60px 0 0 auto;
}
.c-footerLink a {
  padding: 0 0 2px;
  color: #fff;
  transition: 0.4s ease;
}
.c-footerLink a:hover {
  opacity: 0.7;
}
.c-footerLink ul {
  display: -webkit-flex;
  display: -ms-flex;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  position: relative;
  justify-content: flex-end;
  margin: 0 0 45px;
}
.c-footerLink ul li {
  position: relative;
  margin: 0 33px 0 0;
}
.c-footerLink ul li:last-of-type {
  margin: 0;
}
@media screen and (max-width: 768px) {
  footer {
    padding: 4px 0 20px;
  }
  #js-pagetop a::after{
    left: 14px;
  }
  .c-footer {
    padding: 30px 0 0;
  }
  .c-footer h1 {
    width: 155px;
    margin: 0 auto 45px;
  }
  .c-footer-link {
    flex-direction: column;
    margin: 30px 0 30px;
    border-top: 1px solid #fff;
  }
  .c-footer-link li {
    width: 100%;
    padding: 0;
  }
  .c-footer-link li a {
    display: block;
    width: 100%;
    padding: 5px 0;
    border-bottom: 1px solid #fff;
    text-align: center;
  }
  .c-footer-link li::after {
    display: none;
  }
  .c-footerInner {
    flex-direction: column;
  }
  .c-footerLink {
    justify-content: center;
    margin: auto 0;
  }
  .c-footerLink ul {
    flex-direction: column;
  }
  .c-footerLink ul::after {
    display: none;
  }
  .c-footerLink ul li {
    margin: 0 0 10px;
  }
  .c-footerLink ul li::after {
    display: none;
  }
  .c-footerInner {
    margin: 0 0 15px;
  }
  .c-footerCookie p {
    font-size: 12px;
    line-height: 1.4;
    text-align: center;
  }
  footer small {
    display: block;
    padding: 2px 0;
  }
  footer small p {
    color: #fff;
    font-size: 10px;
    text-align: center;
  }
  #js-pagetop {
    right: 15px;
    width: 50px;
    height: 50px;
  }
  #js-pagetop.is-pagetop {
    top: -25px;
  }
  #js-pagetop a::before {
    position: absolute;
    top: 47%;
    left: 55%;
    width: 12px;
    height: 12px;
    content: '';
  }
}

JavaScript例

document.addEventListener('click', function(event) {
    if (event.target.matches('a[href^="#"]')) {
        event.preventDefault();
        let href = event.target.getAttribute('href');
        let target = href === "#" || href === "" ? document.documentElement : document.querySelector(href);
        let position = target.offsetTop;
        window.scrollTo({
            top: position,
            behavior: 'smooth'
        });
    }
});
window.addEventListener('load', function() {
    if (window.location.hash) {
        let target = document.querySelector(window.location.hash);
        if (target) {
            setTimeout(function() {
                window.scrollTo({
                    top: target.offsetTop,
                    behavior: 'smooth'
                });
            }, 100);
        }
    }
});
window.addEventListener('load', function() {
  window.addEventListener('resize', handleScrollResize);
  window.addEventListener('scroll', handleScrollResize);
});
function handleScrollResize() {
  let st = window.pageYOffset || document.documentElement.scrollTop,
      ww = window.innerWidth,
      wh = window.innerHeight,
      fot = document.querySelector('footer').offsetTop,
      fotsp = document.querySelector('footer').offsetTop;
  let pagetop = document.getElementById('js-pagetop');
  if (st > wh) {
    pagetop.classList.add('is-show');
    if (ww > 768) {
      if (st > fot - wh) {
        pagetop.classList.add('is-pagetop');
      } else {
        pagetop.classList.remove('is-pagetop');
      }
    } else {
      if (st > fotsp - wh) {
        pagetop.classList.add('is-pagetop');
      } else {
        pagetop.classList.remove('is-pagetop');
      }
    }
  } else {
    pagetop.classList.remove('is-show');
  }
}

まとめ

今回もjQueryではなく、Vanilla.jsで実装してみました。

コピペしてガンガン使ってください!

WEB制作担当ソーヤ

ソーヤ

上毛印刷WEB制作担当
前職は東証プライム企業の本社WEB受託チームにてフロントエンドエンジニアを3年経験。


この記事に対するご意見・ご感想・ご質問等ありましたら、
ぜひ下記フォームにてお送りください。

    お名前必須
    メールアドレス必須
    お問い合わせ内容必須
    PAGE TOP