skip to Main Content

When I try to make a JavaScript program to create a responsive navigation menu, I get error message that I can’t understand.

When I write the code in Brackets, I get the error "Expected an identifier and instead saw ‘const’.

When I look inspect the webpage and lock at the console, the error is:

menu.js:4 Uncaught TypeError: Cannot read properties of undefined (reading ‘addEventListener’)
at menu.js:4:14

I’m attaching all my code below. The issue, however, seems to be with the JavaScript code so I’ll attach that first since it’s the most important, I believe.

JavaScript code:

const toggleButton = document.getElementsByClassName('toggle-button')[0]
const navbarLinks = document.getElementsByClassName('navbar-links')[0]

toggleButton.addEventListener('click', () => {
    navbarLinks.classList('active')
})

CSS Code:

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    padding: 0;
}

.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #333;
    color: white;
}

.logo {
    font-size: 1.5rem;
    margin: .5rem;
}

.navbar-links ul {
    margin: 0;
    padding: 0;
    display: flex;
}

.navbar-links li {
    list-style: none;
}

.navbar-links li a {
    text-decoration: none;
    color: white;
    padding: 1rem;
    display: block;
}

.navbar-links li:hover {
    background-color: #555;
}

/*STYLES HAMBURGER ICON*/
.toggle-button {
    position: absolute;
    top: .75rem;
    right: 1rem;
    display: none;
    flex-direction: column;
    justify-content: space-between;
    width: 30px;
    height: 21px;
}

.toggle-button .bar {
    height: 3px;
    width: 100%;
    background-color: white;
    border-radius: 10px;
}

/*MOBILE VIEW*/
@media (max-width: 600px) {
    .toggle-button {
        display: flex;
    }
    
    .navbar-links {
        
        display: none;
        width:100%;
}
    
    .navbar {
        flex-direction: column;
        align-items: flex-start;
    }
    
    .navbar-links ul {
        width: 100%;
        flex-direction: column;
    }
    
    .navbar-links li {
        text-align: center;
    }
    
    .navbar-links li a {
       padding: .5rem 1rem;
    }
    
     .navbar-links.active {
        display: flex;
    }
}

Here is my HTML Code:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Responsive Navigation Bar</title>
    <!--RESET-->
    <link rel="stylesheet" href="css/reset.css">

    <!--SITE STYLES-->
    <link rel="stylesheet" href="css/style.css">
    <script src="js/menu.js"></script>

</head>

<body>
    <nav class="navbar">
        <div class="logo">Company Name</div>
        <a href="#" class="toggle-button">
            <span class="bar"></span>
            <span class="bar"></span>
            <span class="bar"></span>
        </a>
        <div class="navbar-links">
            <ul>
                <li><a href="#">Home</a></li>
                <li><a href="#">About</a></li>
                <li><a href="#">Services</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </div>
    </nav>
</body>

</html>

What should be happening is, in the mobile view, when the hamburger icon is clicked on it should pop open and display the links Home, About, Services, Contact and when it’s clicked again, it should disappear.

I tried inserting semi-colons at the end of each statement but that does not work either.

Everything works fine with the HTML and CSS. When I switch to mobile view, the navigation bar disappears and becomes a hamburger icon, as it should. What’s not working is clicking it in mobile view and it popping open. The JavaScript is what’s not working.

2

Answers


  1. Instead of using classList('active'), you should use classList.add('active') to correctly add the class. Here’s the corrected JavaScript code:

    const toggleButton = document.getElementsByClassName('toggle-button')[0];
    const navbarLinks = document.getElementsByClassName('navbar-links')[0];
    
    toggleButton.addEventListener('click', () => {
        navbarLinks.classList.add('active');
    });
    

    With this change, the navigation links should become visible when you click the hamburger icon in mobile view.

    Another approach you could use is to toggle the active class using the classList.toggle() method. This way, the class will be added if it’s not present and removed if it’s already there.

    const toggleButton = document.querySelector('.toggle-button');
    const navbarLinks = document.querySelector('.navbar-links');
    
    toggleButton.addEventListener('click', () => {
        navbarLinks.classList.toggle('active');
    });
    
    Login or Signup to reply.
  2. You have a couple of problems in your code.

    First, since you’re loading JS before your HTML, your JS code won’t find any element in the HTML. To fix this, you either need to put your JS code inside DOMContentLoaded callback or simply put your JS import code at the end of your body.

    Second, classList is not a function, so if you want to toggle classes upon clicking your button, you need to update it as below:

    toggleButton.addEventListener('click', () => {
      navbarLinks.classList.toggle('active');
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search