0
1

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 2024-07-11

はじめに

この記事では、ReactとTypeScriptを使用して、ページを一定の位置までスクロールすると表示されるメニューの作り方をご紹介します。メニューは滑らかにフェードインおよびフェードアウトするようにCSSでアニメーションを追加します。

完成イメージ

ezgif.com-crop.gif

ディレクトリ

scroll-menu
├── node_modules
├── public
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── index.css
│   ├── index.tsx
│   ├── Menu.css
│   └── Menu.tsx
├── tailwind.config.js
├── package.json
└── tsconfig.json

作り方

1. プロジェクトのセットアップ

まず、TypeScriptを使用したReactプロジェクトを作成して、Tailwind CSSとdaisyUIをインストールします。

npx create-react-app scroll-menu --template typescript
cd scroll-menu
npm install -D tailwindcss 
npx tailwindcss init -p
npm install daisyui

2. Tailwind CSSとdaisyUIの設定

tailwind.config.js ファイルを以下のように設定します。

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [require("daisyui")],
};

src/index.css ファイルにTailwind CSSのベーススタイルをインポートします。

@tailwind base;
@tailwind components;
@tailwind utilities;

3. Menuコンポーネントの作成

次に、Menuコンポーネントを作成します。src/Menu.tsx ファイルを作成し、以下のコードを追加します。

import React from 'react'
import "./Menu.css";

interface MenuProps {
  show: boolean;
}

const Menu: React.FC<MenuProps> = ({show}) => {
  return (
    <ul className={`menu bg-base-200 rounded-box w-56 ${show ? 'show' : ''}`}>
      <li>
        <h2 className="menu-title">Title</h2>
        <ul>
          <li><a>Item 1</a></li>
          <li><a>Item 2</a></li>
          <li><a>Item 3</a></li>
        </ul>
      </li>
    </ul>
  );
}

export default Menu

show については、この後に説明するスクロールイベントの処理で管理していて、親コンポーネントの App.tsx から子コンポーネントの Menu.tsx にPropsとして渡されてきます。

この行の ${show ? 'show' : ''} で渡されてきた show プロパティの値に基づいて CSSの show クラスを動的に追加しています。 true の場合は show クラスが追加され、メニューが表示されます。 false の場合は show クラスが追加されず、メニューは非表示のままです。

bg-base-200 rounded-box w-56 はdaisyUIが提供しているスタイルです。

<ul className={menu bg-base-200 rounded-box w-56 ${show ? 'show' : ''}}>

4. CSSの設定

表示/非表示のアニメーションを追加するために、CSSファイルを作成して設定します。src/Menu.css ファイルを作成し、以下の内容を追加します。

daisyUIで設定している menu クラスに位置の調整と表示・非表示のスタイルを追加しています。

.menu {
  position: fixed;
  top: 15px;
  right: 25px;
  opacity: 0;
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.menu.show {
  opacity: 1;
} 

5. スクロールイベントの処理

次に、スクロールイベントを処理してメニューの表示/非表示を切り替えるコードをsrc/App.tsx に追加します。

import React, { useEffect, useState } from 'react';
import './App.css';
import Menu from './Menu';

function App() {
  const [showMenu, setShowMenu] = useState(false)

  const handleScroll = () => {
    const scrollTop = window.scrollY;
    if (scrollTop > 50) { // 50px以上スクロールしたら表示
      setShowMenu(true);
    } else {
      setShowMenu(false)
    }
  };

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

  return (
    <div className="App">
      <header className="App-header">
        <h1 className="text-4xl font-bold text-black">Scroll Menu</h1>
      </header>
      <Menu show={showMenu} />
    </div>
  );
}

export default App;

handleScroll 関数でスクロールに位置をチェックして、showMenu の状態を更新します。今回の場合、スクロールの位置が50px以上でメニューを表示それ以外で非表示の切り替えをしています。

const handleScroll = () => {
    const scrollTop = window.scrollY;
    if (scrollTop > 50) { // 50px以上スクロールしたら表示
      setShowMenu(true);
    } else {
      setShowMenu(false)
    }
  };

以下は、コンポーネントが初めてレンダリングされたときにスクロールイベントリスナーを追加し、ユーザーがページをスクロールするたびに handleScroll 関数が実行されるようにしています。

また、return () => { window.removeEventListener("scroll", handleScroll); }; でコンポーネントが破棄されるときにイベントリスナーを削除することで、不要なイベント処理を防いでいます。

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

親コンポーネントの App.tsx から子コンポーネントの Menu.tsx へPropsを渡しています。 showMenu は親コンポーネントで管理されているスクロールイベントの状態で、true または false になります。

 <Menu show={showMenu} />

おわりに

以上で、ReactとTypeScriptを使用してスクロール時に表示されるメニューの作り方を説明しました。この方法を使えば、ユーザーが特定の位置までスクロールしたときにメニューを表示するインタラクティブなWebアプリケーションを簡単に作成できます。必要に応じてカスタマイズして、自分のプロジェクトに取り入れてみてください。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?