9
8

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 1 year has passed since last update.

スクロール途中でトップに戻るボタンをReactでやってみる

Last updated at Posted at 2023-03-06

先日、マークアップ能力向上のためにReactを使ってサイトを作成しました。
今回は、その過程で作ったスクロール途中にトップに戻るボタンを表示する方法を残します。

コードはこちらになります。

import { useEffect, useState } from 'react'
import styled from "styled-components";
import { Link as Scroll } from 'react-scroll';

const ReturnTopButton = () => {
  const [isButtonActive, setIsButtonActive] = useState(false)

  const returnTop = () => {
    window.scrollTo({
      top: 0,
      behavior: 'smooth'
    })
  }

  useEffect(() => {
    window.addEventListener('scroll', scrollWindow)
    return () => {
      window.removeEventListener('scroll', scrollWindow)
    }
  }, [])

  const scrollWindow = () => {
    const top = 700  //ボタンを表示させたい位置
    let scroll = 0
    scroll = window.scrollY
    if (top <= scroll) {
      setIsButtonActive(true)
    } else {
      setIsButtonActive(false)
    }
  }

  const normalStyle = {
    opacity: 0,
    transition: '0.5s',
    pointerEvents: 'none'
  }
  const activeStyle = {
    opacity: 1,
    transition: '0.5s'
  }
  const style = isButtonActive ? activeStyle : normalStyle

  return (
    <StyledTopButton>
      <button className="Top" style={style} onClick={returnTop}>
        <Scroll to="Home" smooth={true} duration={500}></Scroll>
      </button>
    </StyledTopButton>
  )
}

export default ReturnTopButton

const StyledTopButton = styled.div`
  .Top {
    position: fixed;
    right: 4rem;
    bottom: 2.5rem;
    width: 5rem;
    height: 5rem;
    box-sizing: border-box;
    border: 1px solid WHITE;
    border-radius: 50%;
    background-color: #121212;
    
    a {
      position: relative;
      display: block;
      transition: .3s;
      width: 5rem;
      height: 5rem;

      &:before {
        content: '';
        position: absolute;
        right: 37%;
        top: 40%;
        width: 0;
        height: 0;
        border-left: 0.7rem solid transparent;
        border-right: 0.7rem solid transparent;
        border-bottom: 0.7rem solid WHITE;
      }
    }
  }
`

スクロールが発生するたびに、scrollWindow関数を実行し、
現在の位置がトップに戻るボタンを表示したい位置を超えていたら、ボタンを表示させます。
表示したい位置を超えていなければボタンを非表示にします。

useEffect(() => {
  window.addEventListener('scroll', scrollWindow)
  return () => {
    window.removeEventListener('scroll', scrollWindow)
  }
}, [])

const scrollWindow = () => {
  const top = 700  //ボタンを表示させたい位置
  let scroll = 0
  scroll = window.scrollY
  if (top <= scroll) {
     setIsButtonActive(true)
  } else {
    setIsButtonActive(false)
  }
}

スクロールのスピードと表示・非表示による切り替えは下記部分です。

const normalStyle = {
    opacity: 0,
    transition: '0.5s',
    pointerEvents: 'none'
  }
  const activeStyle = {
    opacity: 1,
    transition: '0.5s'
  }
  const style = isButtonActive ? activeStyle : normalStyle

CSS部分は下記部分です。

const StyledTopButton = styled.div`
  .Top {
    position: fixed;
    right: 4rem;
    bottom: 2.5rem;
    width: 5rem;
    height: 5rem;
    box-sizing: border-box;
    border: 1px solid WHITE;
    border-radius: 50%;
    background-color: #121212;
    
    a {
      position: relative;
      display: block;
      transition: .3s;
      width: 5rem;
      height: 5rem;

      &:before {
        content: '';
        position: absolute;
        right: 37%;
        top: 40%;
        width: 0;
        height: 0;
        border-left: 0.7rem solid transparent;
        border-right: 0.7rem solid transparent;
        border-bottom: 0.7rem solid WHITE;
      }
    }
  }
`

完成です。
トップに戻るボタン.gif

9
8
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
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?