记录一次自己反复修改实现的导航栏效果 具体展示会在完工后上线 期间遇到各种bug 最终修复成功 实现了我想要的效果
- 在components目录下创建 Navbar.js
'use client';
import Link from 'next/link';
import { useState, useEffect } from 'react';
import { lora } from 'utils/font';
import { cn } from 'utils/misc';
import { Menu, X } from 'lucide-react';
const navFontClass = cn(
lora.className,
'text-white hover:text-rose-300 transition duration-300 text-lg'
);
const Navbar = () => {
const [nav, setNav] = useState(false);
const [scrollPos, setScrollPos] = useState(0);
const [hidden, setHidden] = useState(false);
// 处理滚动事件
useEffect(() => {
const handleScroll = () => {
const currentScrollPos = window.pageYOffset || document.documentElement.scrollTop;
if (nav) return;
if (currentScrollPos > scrollPos + 5) {
setHidden(true);
} else if (currentScrollPos < scrollPos - 5) {
setHidden(false);
}
setScrollPos(currentScrollPos <= 0 ? 0 : currentScrollPos);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [scrollPos, nav]);
// 处理窗口大小变化
useEffect(() => {
const handleResize = () => {
if (window.innerWidth >= 768) {
setNav(false); // 切换到桌面端时关闭菜单
}
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
const scrollToTop = () => {
const scrollDuration = 1000;
const scrollStep = -window.scrollY / (scrollDuration / 16);
const scrollAnimation = () => {
if (window.scrollY !== 0) {
window.scrollBy(0, scrollStep);
requestAnimationFrame(scrollAnimation);
}
};
requestAnimationFrame(scrollAnimation);
};
return (
<nav className={`navbar ${hidden ? 'navbar-hidden' : 'navbar-visible'} bg-transparent p-4 w-full z-10`}>
<div className="flex justify-between items-center w-full">
<div className={`${navFontClass} font-bold pl-4`}>
<Link href="/" onClick={(e) => { e.preventDefault(); scrollToTop(); }}>
Dark.Lotus
</Link>
</div>
{/* Desktop Links */}
<div className="hidden md:flex space-x-8 pr-4">
<Link href="https://darklotus.cn" target="_blank" className={navFontClass}>Home</Link>
<Link href="https://blog.darklotus.cn" target="_blank" className={navFontClass}>Blog</Link>
<Link href="/projects" className={navFontClass}>Docs</Link>
<Link href="/contact" className={navFontClass}>About</Link>
</div>
{/* Mobile Menu Button */}
<div className="md:hidden pr-4 z-20">
<button onClick={() => setNav(!nav)} className={navFontClass}>
{nav ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
</div>
{/* Mobile Menu Overlay */}
{nav && (
<div className="menu-overlay" onClick={() => setNav(false)}>
<div className="menu-content" onClick={(e) => e.stopPropagation()}>
<Link href="/" onClick={(e) => { e.preventDefault(); scrollToTop(); setNav(false); }} className={`block py-4 text-white ${navFontClass}`}>
Home
</Link>
<Link href="https://blog.darklotus.cn" target="_blank" rel="noopener noreferrer" onClick={() => setNav(false)} className={`block py-4 text-white ${navFontClass}`}>
Blog
</Link>
<Link href="https://docs.darklotus.cn" target="_blank" rel="noopener noreferrer" onClick={() => setNav(false)} className={`block py-4 text-white ${navFontClass}`}>
Docs
</Link>
<Link href="https://about.darklotus.cn" target="_blank" rel="noopener noreferrer" onClick={() => setNav(false)} className={`block py-4 text-white ${navFontClass}`}>
About
</Link>
</div>
</div>
)}
</nav>
);
};
export default Navbar;
index.tsx 首页引用
// Import the Navbar component import Navbar from 'components/Navbar';
插入导航栏组件
ps:以下代码是的摆放位置 不能直接复制粘贴! export function Home() { return ( <main className="w-full overflow-hidden"> {/* Include the Navbar component */} <Navbar />
4.全局CSS
/* 手机端导航栏 */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
transition: transform 0.3s ease-in-out;
}
.navbar-hidden {
transform: translateY(-100%);
}
.menu-overlay {
background-color: rgba(0, 0, 0, 0.8); /* 半透明黑色背景 */
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 10; /* 确保菜单在其他内容之上 */
}
.menu-content {
background-color: transparent; /* 菜单内容的背景色 */
padding: 2rem; /* 菜单内容的内边距 */
border-radius: 0.5rem; /* 菜单内容的圆角 */
text-align: center;
}
/* 导航栏桌面端 */
@media (min-width: 768px) {
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
transition: transform 0.3s ease-in-out;
}
.navbar-hidden {
transform: translateY(-100%);
}
.navbar-visible {
transform: translateY(0);
}
}