Reputation: 13
I'm using Next Js with Tailwind CSS for creating the website. Use Javascript to toggle the menu for Mobile devices. But Next Js click the nav menu link not closing the opened nav.
Button-
const Navbar = () => {
const [ isHidden, setIsHidden ] = useState(true)
return (
<>
<button onClick={() => setIsHidden(c => !c)} className="menu-button md:hidden rounded-lg focus:outline-none focus:shadow-outline">
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path strokeLinecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
<path className="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
<nav className={`mobile-menu flex-col flex-grow pb-4 md:pb-0 md:flex md:justify-end md:flex-row flex hidden ${isHidden ? "hidden" : ""}`}>
<Link href="/about">
<a className="md:mt-0 mt-3 px-3 py-2">About</a>
</Link>
<Link href="/about-us">
<a className="md:mt-0 mt-3 px-3 py-2">Boost</a>
</Link>
<Link href="/about-us">
<a className="md:mt-0 mt-3 px-3 py-2">Technology</a>
</Link>
<Link href="/about-us">
<a className="md:mt-0 mt-3 px-3 py-2">Contact</a>
</Link>
</nav>
</>
)
}
export default Navbar
Using the below Javascript for toggle Menu.
const btn = document.querySelector('button.menu-button');
const menu = document.querySelector(".mobile-menu");
btn.addEventListener("click", () => {
menu.classList.toggle("hidden");
})
Upvotes: 1
Views: 3317
Reputation: 888
Next.js preserves state between route changes. You can listen for click events on the menu div. If the click event comes from an <a>
tag or bubbles through one close the menu.
function handleMenuClick(event) {
const path = event.nativeEvent.composedPath()
for (const element of path) {
if (element.tagName === 'A') {
setIsOpen(false)
break
}
}
}
And attach the event listener to the menu div as such:
<nav className="mobile-menu" onClick={handleMenuClick}>
<Link href="/1">Link 1</Link>
<Link href="/2">Link 2</Link>
<Link href="/3">Link 3</Link>
</nav>
Upvotes: 0
Reputation: 615
It may be that your event listener was created multiple times (we don't see the whole code). More React like approach could look like this:
const Home = () => {
const [ isHidden, setIsHidden ] = useState(true)
return (
<button onClick={() => setIsHidden(c => !c)}>click me</button>
<nav className={`your classes ${isHidden ? "hidden" : ""}`}>
...
</nav>
)
}
So you have a state and based on that state you are adding "hidden" class. Button has an onclick handler which toggles the state.
If you want to close navbar also on link click you can try this approach:
<Link href="/about">
<a
onClick={(e) => {
e.preventDefault()
setIsHidden(true)
}
>About</a>
</Link>
Upvotes: 4