ํ๋ก๊ทธ๋๋ฐ ์ธ๊ณ๋ฅผ ํ๊ตฌํฉ์๋ค.
์คํฌ๋กค์ ๋ฐ๋ผ ๋ํ๋๊ณ ์ฌ๋ผ์ง๋ ๋ค๋น๊ฒ์ด์ ๋ฐ ๊ตฌํํ๊ธฐ
์ด๋ฒ ํ๋ก์ ํธ์์ ์คํฌ๋กค์ ๋ฐ๋ผ ๋ํ๋๊ณ ์ฌ๋ผ์ง๋ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ๊ตฌํํ์ต๋๋ค.
์คํฌ๋กค์ ๋ด๋ฆด ๋๋ ์ฌ๋ผ์ก๋ค๊ฐ, ์คํฌ๋กค์ ์ฌ๋ฆฌ๋ฉด ๋ค์ ๋ํ๋ฉ๋๋ค.
๊ตฌํ ํ๋ฉด
์์ฑ ์ฝ๋
๋ง์ง๋ง ์คํฌ๋กค ์์น๋ฅผ ๊ธฐ์ตํ์ฌ ๋ค๋น๊ฒ์ด์ ๋ฐ์ ํ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ์ฝ๋์ ๋๋ค.
์คํฌ๋กค์ด ์๋๋ก ์งํ ์ค์ด๋ฉด false, ์คํฌ๋กค์ด ์๋ก ์งํ ์ค์ด๋ฉด true๋ก ์ค์ ํ์ฌ ๋ฐ ์ํ๋ฅผ ๋ณ๊ฒฝํ์์ต๋๋ค.
Nav.jsx
import { useEffect, useState } from 'react';
import style from './Nav.module.css'
import { Link } from 'react-router-dom';
function Nav() {
// ๋ค๋น๊ฒ์ด์
๋ฐ ํ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ state
const [showNav, setShowNav] = useState(true);
// ๋ง์ง๋ง ์คํฌ๋กค ์์น๋ฅผ ์ ์ฅํ๋ state
const [lastScrollY, setLastScrollY] = useState(0);
useEffect(() => {
// ์คํฌ๋กค ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์
const handleScroll = () => {
const currentScrollY = window.scrollY;
// ์คํฌ๋กค์ด ์๋๋ก ์งํ๋์๋์ง ํ์ธ
if (currentScrollY > lastScrollY) {
setShowNav(false); // ์คํฌ๋กค์ ๋ด๋ฆด ๋ ๋ค๋น๊ฒ์ด์
๋ฐ ์จ๊ธฐ๊ธฐ
} else {
setShowNav(true); // ์คํฌ๋กค์ ์ฌ๋ฆด ๋ ๋ค๋น๊ฒ์ด์
๋ฐ ํ์
}
// ๋ง์ง๋ง ์คํฌ๋กค ์์น ์
๋ฐ์ดํธ
setLastScrollY(currentScrollY);
};
// ์คํฌ๋กค ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฑ๋ก
window.addEventListener('scroll', handleScroll);
// ํด๋ฆฐ์
ํจ์์์ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ
return () => window.removeEventListener('scroll', handleScroll);
}, [lastScrollY]); // lastScrollY๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค useEffect๊ฐ ์คํ๋ฉ๋๋ค.
return (
<div className={`${style.header} ${showNav ? '' : style.hideNav}`}>
<Link className={style.Logo} to="/">
<img src={`${process.env.PUBLIC_URL}/img/logo.svg`} alt="MDS Logo" className={style.logo} />
</Link>
<div className={style.navbar}>
<Link className={style.navbarMenu} to={'/map'}>
<img src={`${process.env.PUBLIC_URL}/img/mountainpath.svg`} alt="๋ฑ์ฐ ์ ๋ณด ์์ด์ฝ" className={style.icon1} />๋ฑ์ฐ ์ ๋ณด
</Link>
<Link className={style.navbarMenu} to={'/review'}>
<img src={`${process.env.PUBLIC_URL}/img/flag.svg`} alt="๋ฑ์ฐ ํ๊ธฐ ์์ด์ฝ" className={style.icon2} />๋ฑ์ฐ ํ๊ธฐ
</Link>
<Link className={style.navbarMenu} to={'/rec'}>
<img src={`${process.env.PUBLIC_URL}/img/mountainrec.svg`} alt="๋ฑ์ฐ๋ก ์ถ์ฒ ์์ด์ฝ" className={style.icon1} />๋ฑ์ฐ๋ก ์ถ์ฒ๋ฐ๊ธฐ
</Link>
</div>
</div>
)
}
export default Nav;
Nav.module.css
.hidenav ์คํ์ผ์์ navbar๋ฅผ ์จ๊ธฐ๋ ํจ๊ณผ๋ฅผ ์ ์ฉํฉ๋๋ค.
.header {
display: flex;
align-items: center;
background-color: rgba(179, 179, 179, 0.42);
padding-left: 2rem;
z-index: 1000;
/* ๋ค๋ฅธ ์์๋ค ์์ ์ค๋๋ก z-index ์ค์ */
position: fixed;
transition: transform 0.3s ease;
/* transform ์์ฑ์ ๋ํ ์ ํ ํจ๊ณผ */
}
.logo {
width: 12rem;
height: 5rem;
}
.icon1 {
width: 3rem;
height: 1.5rem;
}
.icon2 {
width: 2rem;
height: 1.1rem;
}
.navbar {
justify-content: center;
width: 100vw;
text-align: center;
font-size: 1.2rem;
}
.navbarMenu {
margin: 5rem;
text-decoration: none;
color: rgb(0, 0, 0);
transition: color 0.3s ease;
/* ์์ ๋ณํ์ ์ ๋๋ฉ์ด์
ํจ๊ณผ๋ฅผ ์ถ๊ฐํฉ๋๋ค */
position: relative;
/* ๊ฐ์ ์์์ ๊ธฐ์ค์ ์ค์ */
overflow: hidden;
/* ๋ฐ์ค์ด ๋งํฌ ์์ญ ๋ฐ๊นฅ์ผ๋ก ๋๊ฐ์ง ์๋๋ก ์ค์ */
}
.navbarMenu:hover {
color: #3ca50f;
/* ๋ง์ฐ์ค ์ค๋ฒ ์ ๊ธ์ ์์์ ๋ณ๊ฒฝํฉ๋๋ค */
}
.navbarMenu::after {
content: '';
/* ๊ฐ์ ์์์ ๋ด์ฉ์ ๋น์๋ก๋๋ค */
position: absolute;
left: 0%;
/* ์ผ์ชฝ์์ 50%์ ์์น์์ ์์ */
bottom: -0.5rem;
/* ๋งํฌ ๋ฐ๋ฅ์ผ๋ก๋ถํฐ -0.5rem ์์ ์์น */
width: 0;
/* ์ด๊ธฐ ๋๋น๋ 0์ผ๋ก ์ค์ ํ์ฌ ๋ณด์ด์ง ์๊ฒ ํฉ๋๋ค */
height: 0.13rem;
/* ๋ฐ์ค์ ๋๊ป */
background: rgba(0, 0, 0, 0.279);
/* ๋ฐ์ค์ ์์ */
transition: width 0.5s ease, left 0.5s ease;
/* ๋๋น์ ์์น์ ๋ํ ์ ํ ํจ๊ณผ ์ค์ */
}
.navbarMenu:hover::after,
.navbarMenu:focus::after {
width: 100%;
/* ๋ง์ฐ์ค๋ฅผ ์ฌ๋ฆฌ๊ฑฐ๋ ํฌ์ปค์ค ์ ๋ฐ์ค์ ๋๋น๋ฅผ 100%๋ก ๋ณ๊ฒฝ */
left: 0;
/* ์์น๋ฅผ ์ผ์ชฝ ๋์ผ๋ก ๋ณ๊ฒฝ */
}
/* Nav.module.css */
.hideNav {
transform: translateY(-100%);
/* ๋ค๋น๊ฒ์ด์
๋ฐ๋ฅผ ์๋ก ์จ๊น๋๋ค */
transition: transform 0.3s ease;
/* ๋ถ๋๋ฌ์ด ์ ํ ํจ๊ณผ */
}
์์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์คํฌ๋กค์ ๋ฐ๋ผ ์ฌ๋ผ์ง๊ณ ๋ํ๋๋ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.