search
  • Sign In
  • Sign Up
Password reset successful

Follow the proiects vou are interested in andi aet the latestnews about them taster

Table of Contents
Initial settings: opening and closing logic of hamburger menu
Solution: Listen to navigation link click events
Complete sample code
Things to note and best practices
Home Web Front-end HTML Tutorial Implementing a responsive navigation menu: JavaScript practice to automatically close the menu when clicking a link

Implementing a responsive navigation menu: JavaScript practice to automatically close the menu when clicking a link

Nov 08, 2025 pm 07:15 PM

Implementing a responsive navigation menu: JavaScript practice to automatically close the menu when clicking a link

This article details how to optimize the user experience of responsive navigation menus. For the common problem of the hamburger menu remaining open after clicking the navigation link, the tutorial provides a JavaScript-based solution. By adding a unified class name to the navigation link and listening for click events, we can automatically close the menu after the user selects the target page, thereby improving the interactive fluency and user-friendliness of the website.

In modern web development, responsive navigation menus (often presented as a "hamburger" icon) are an indispensable UI element on mobile devices. When a user clicks on the hamburger icon, a full-screen or side navigation menu expands to reveal various parts of the site. However, a common user experience issue is that the menu remains open after the user clicks a link in the menu and jumps to the target content. This may not only block some content, but also require additional actions for the user to close the menu. This tutorial will guide you on how to use JavaScript to automatically close the menu after clicking a navigation link, thereby optimizing the user experience.

Initial settings: opening and closing logic of hamburger menu

First, let's look at a typical hamburger menu implementation that uses JavaScript to toggle the visibility of the navigation list.

HTML structure:

 <header>
    <div class="hamburger" id="hamburger"></div>
    <ul class="list" id="list">
        <li><a href="#home">HOME</a></li>
        <li><a href="#services">SERVICES</a></li>
        <li><a href="#about">ABOUT</a></li>
        <li><a href="#menu">MENU</a></li>
    </ul>
</header>

<div class="contents">
    <h1 id="home">HOME</h1>
    <h1 id="services">SERVICES</h1>
    <h1 id="about">ABOUT</h1>
    <h1 id="menu">MENU</h1>
</div>

CSS style:

 /* Basic reset*/
body {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html {
    scroll-behavior: smooth; /* Smooth scrolling effect*/
}
ul {
    list-style-type: none; /* Remove list style*/
}

/* The default hidden state of the navigation list */
.list {
    list-style-type: none;
    display: none; /* hidden by default */
}

/* Navigation list display status */
.list.show {
    position: fixed;
    display: block; /* display*/
    inset: 0 0 0 0; /* Full screen coverage*/
    z-index: 99;
    text-align: center;
    background-color: hsl(0 0% 0% / 0.6); /* Semi-transparent background*/
    padding: min(43vh, 20rem) 2rem; /* vertically centered content*/
}

/*Header and hamburger button styles*/
header {
    display: flex;
    justify-content: space-between;
}
.hamburger {
    width: 50px;
    height: 50px;
    background-color: red;
    cursor: pointer;
    position: absolute;
    z-index: 999;
}

/* Page content style*/
h1 {
    margin: 20rem 0;
}
.contents {
    position: absolute;
    left: 50%;
    top: 120%;
    transform: translate(-50%, -50%);
}

JavaScript logic:

 const button = document.getElementById("hamburger");
const list = document.getElementById("list");

button.addEventListener("click", () =&gt; {
    list.classList.toggle('show'); // Click the hamburger button to toggle the menu display/hide});

The above code implements showing or hiding the navigation menu by switching the show class of the list element when the hamburger button is clicked. However, when the menu is displayed and you click any of the navigation links (such as "HOME", "SERVICES", etc.), the menu will not automatically close.

To solve the above problem, we need to add a click event listener for each navigation link. When the user clicks on these links, in addition to triggering the default page scrolling behavior, we also need to explicitly remove the show class of the navigation menu to close it.

Step 1: Modify the HTML and add a common class name to the navigation link

In order to easily select all navigation links, we add a unified class name to each tag, such as nav-item.

 

Step 2: Add JavaScript logic to listen for navigation link click events

Now, we can use document.querySelectorAll to select all elements with nav-item class and add click event listeners to each of them. In the event callback function, we directly remove the show class of the list element.

 const navItems = document.querySelectorAll('.nav-item'); // Note that the selector is '.nav-item'
navItems.forEach((navItem) =&gt; {
    navItem.addEventListener('click', () =&gt; {
        list.classList.remove("show"); // Remove the 'show' class to close the menu when a navigation link is clicked});
});

Complete sample code

Integrate the above modifications together to form a complete and fully functional hamburger menu implementation:

HTML (index.html):

 


    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Navigation Menu</title>
    <link rel="stylesheet" href="style.css">


    <header>
        <div class="hamburger" id="hamburger"></div>
        <ul class="list" id="list">
            <li><a href="#home" class="nav-item">HOME</a></li>
            <li><a href="#services" class="nav-item">SERVICES</a></li>
            <li><a href="#about" class="nav-item">ABOUT</a></li>
            <li><a href="#menu" class="nav-item">MENU</a></li>
        </ul>
    </header>

    <div class="contents">
        <h1 id="home">HOME</h1>
        <h1 id="services">SERVICES</h1>
        <h1 id="about">ABOUT</h1>
        <h1 id="menu">MENU</h1>
    </div>

    <script src="script.js"></script>

CSS (style.css):

 body {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: sans-serif;
}
html {
    scroll-behavior: smooth;
}
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
}
a {
    text-decoration: none;
    color: inherit;
}

.list {
    display: none;
    list-style-type: none;
}
.list.show {
    position: fixed;
    display: flex; /* Use flexbox to center content*/
    flex-direction: column;
    justify-content: center;
    align-items: center;
    inset: 0 0 0 0;
    z-index: 99;
    background-color: hsl(0 0% 0% / 0.8); /* Adjust background transparency*/
    padding: 2rem;
    color: white;
}
.list.show li {
    margin-bottom: 2rem;
}
.list.show a {
    font-size: 2rem;
    font-weight: bold;
    transition: color 0.3s ease;
}
.list.show a:hover {
    color: lightblue;
}

header {
    display: flex;
    justify-content: flex-end; /* Move the hamburger button to the right*/
    padding: 1rem;
    position: relative;
    z-index: 100; /* Make sure the hamburger button is above the menu*/
}
.hamburger {
    width: 50px;
    height: 50px;
    background-color: red;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 5px;
}
/* You can add an icon to the hamburger button, such as using pseudo elements or SVG */
.hamburger::before {
    content: '';
    display: block;
    width: 30px;
    height: 3px;
    background-color: white;
    box-shadow: 0 -10px 0 white, 0 10px 0 white;
}

.contents {
    padding: 2rem;
    text-align: center;
}
.contents h1 {
    margin: 15rem 0; /* Adjust spacing for scrolling */
    font-size: 3rem;
    color: #333;
}

JavaScript (script.js):

 const button = document.getElementById("hamburger");
const list = document.getElementById("list");
const navItems = document.querySelectorAll('.nav-item');

// Listen to the hamburger button click event and switch the menu to show/hide button.addEventListener("click", () =&gt; {
    list.classList.toggle('show');
});

// Listen to each navigation link click event and close the menu navItems.forEach((navItem) =&gt; {
    navItem.addEventListener('click', () =&gt; {
        list.classList.remove("show"); // Remove the 'show' class to close the menu});
});

Things to note and best practices

  1. classList.remove vs. classList.toggle: In the scenario of closing the menu, it is safer to use classList.remove("show") than classList.toggle("show"). Because toggle decides to add or remove based on whether the class currently exists, if the menu has been closed under certain circumstances and toggle is called, it may accidentally reopen the menu. Remove ensures that regardless of the current state of the menu, an attempt is made to close it.

  2. Accessibility: To improve the user experience, especially for users using keyboards or screen readers, consider adding the following enhancements:

    • ARIA attributes: Add aria-expanded and aria-controls attributes to the hamburger button, and dynamically update the value of aria-expanded when the menu is opened and closed.
    • Keyboard navigation: Ensure users can use the Tab key to navigate between menu items and the Enter key to activate links. At the same time, you can consider allowing the user to close the menu by pressing the Esc key when the menu is open.
  3. Event Delegation: For complex menus with a large number of navigation links, adding separate event listeners for each link may slightly impact performance. In this case, you can consider using event delegation, that is, only add an event listener on the parent element (such as ul.list), and then use event.target to determine which child link was clicked.

     list.addEventListener('click', (event) =&gt; {
        if (event.target.classList.contains('nav-item')) {
            list.classList.remove("show");
        }
    });

    This method reduces the number of event listeners and improves efficiency.

  4. Animation effect: For a smoother user experience, you can add transition animation for the display/hiding of the menu in CSS. For example, add transitions for the opacity and transform properties.

Through the above method, we not only solved the problem of the hamburger menu not automatically closing after clicking the link, but also improved the overall user interaction experience and made the responsive navigation menu more intuitive and efficient.

The above is the detailed content of Implementing a responsive navigation menu: JavaScript practice to automatically close the menu when clicking a link. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

ArtGPT

ArtGPT

AI image generator for creative art from text prompts.

Stock Market GPT

Stock Market GPT

AI powered investment research for smarter decisions

Popular tool

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to correctly migrate jQuery's drag and drop events to native JavaScript How to correctly migrate jQuery's drag and drop events to native JavaScript Mar 06, 2026 pm 05:15 PM

This article explains in detail the key pitfalls when migrating jQuery drag-and-drop logic (such as dragover/dragleave) to Vanilla JS - especially the problem of misuse of e.originalEvent causing dataTransfer failure, and provides directly runnable fixes and best practices.

How to make the images in a div fill with no margins while retaining the inner margins of the text How to make the images in a div fill with no margins while retaining the inner margins of the text Mar 07, 2026 pm 10:54 PM

This article explains how to keep the overall padding of the container so that the internal images are displayed close to the edge of the container, while the text content still maintains normal padding - the core is to separate the style scope and achieve precise layout through positioning and box model control.

Solve the problem of unexpected offset of Flex container due to the font size change of the first child element Solve the problem of unexpected offset of Flex container due to the font size change of the first child element Mar 09, 2026 pm 08:15 PM

When the first child element of a Flex container dynamically adjusts the font-size, the container will be vertically offset along the inline baseline; while a normal block-level container will change in height due to the linkage between line height and font measurement. The root cause lies in the baseline alignment mechanism of the Flex container. By default, the baseline of the first child is the container baseline. This can be completely solved through vertical-align: top or explicit baseline control.

Chart.js complete implementation solution for dynamically switching chart types (line chart, bar chart, pie chart) Chart.js complete implementation solution for dynamically switching chart types (line chart, bar chart, pie chart) Mar 12, 2026 pm 08:51 PM

This article explains in detail how to safely and reliably dynamically switch chart types (line/bar/pie) in Chart.js, and solve the problem of Cannot read properties of undefined errors caused by mismatched data structures and rendering exceptions after type switching. The core lies in destroying old instances, deep copying configurations, and accurately rebuilding data structures by type.

A complete guide to using the keyboard to control the smooth movement of HTML elements A complete guide to using the keyboard to control the smooth movement of HTML elements Mar 13, 2026 pm 10:18 PM

This article explains in detail why transform: translate() combined with the keydown event cannot move elements, and provides a reliable solution based on CSS positioning and JavaScript, covering absolute positioning settings, coordinate update logic, code robustness optimization, and common pitfalls.

How to properly override default styles and implement custom CSS layouts in Divi theme builder How to properly override default styles and implement custom CSS layouts in Divi theme builder Mar 14, 2026 am 12:00 AM

This article explains in detail the root cause of style failure when applying custom CSS in the WordPress Divi theme builder. It provides practical solutions for improving selector specificity, accurately positioning elements, and rational use of !important, as well as debugging tips and code optimization examples.

How to dynamically pass HTML form data to analytics.track() method How to dynamically pass HTML form data to analytics.track() method Mar 13, 2026 pm 10:57 PM

This article explains in detail how to safely and efficiently extract user input from HTML forms and structure it into JavaScript objects as attribute parameters of analytics.track() to avoid hard coding and syntax errors and support flexible expansion.

How to optimize Lighthouse image scoring while maintaining high image quality How to optimize Lighthouse image scoring while maintaining high image quality Mar 11, 2026 pm 09:39 PM

This article explores why providing 2x images to high DPR devices may lower Lighthouse performance scores, and provides practical solutions to balance visual quality and real performance: including proper srcset configuration, image compression strategies, modern format selection, and load priority control.

Related articles