What is the best way to conceal a menu after clicking on #links (links leading to sections on the same page)?

How can I hide my hamburger menu when any of the #links (same page links) are clicked or when someone clicks outside the menu area? I believe I need to modify my JS script, but I'm not sure which part needs changing. I am completely new to JavaScript.

const menuBtn = document.querySelector('.menu-btn');
let menuOpen = false;
menuBtn.addEventListener('click', () => {
  if (!menuOpen) {
    menuBtn.classList.add('open');
    document.getElementById("mymobilemenu").style.display = "block";
    menuOpen = true;
  } else {
    menuBtn.classList.remove('open');
    document.getElementById("mymobilemenu").style.display = "none";
    menuOpen = false;
  }
});
.menu-btn {
  position: relative;
  float: right;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80px;
  height: 80px;
  cursor: pointer;
  transition: all .5s ease-in-out;
  border: 3px solid blueviolet;
  background: pink;
}

.menu-btn-burger {
  width: 50px;
  height: 6px;
  background: yellow;
  border-radius: 5px;
  transition: all .5s ease-in-out;
}

.menu-btn-burger::before,
.menu-btn-burger::after {
  content: '';
  position: absolute;
  width: 50px;
  height: 6px;
  background: grey;
  border-radius: 5px;
  transition: all .5s ease-in-out;
}

.menu-btn-burger::before {
  transform: translateY(-16px);
}

.menu-btn-burger::after {
  transform: translateY(16px);
}


/* animation of burger */

.menu-btn.open .menu-btn-burger {
  transform: translateX(-50px);
  background: transparent;
  box-shadow: none;
}

.menu-btn.open .menu-btn-burger::before {
  transform: rotate(45deg) translate(35px, -35px);
}

.menu-btn.open .menu-btn-burger::after {
  transform: rotate(-45deg) translate(35px, 35px);
}

#mymobilemenu {
  display: none;
}
<div class="menu-btn">
  <div class="menu-btn-burger">
  </div>
</div>

<div id="mymobilemenu">
  <li><a href="#section1">section1</a></li>
  <li><a href="#section2">section2</a></li>
  <li><a href="#section3">section3</a></li>
  <li><a href="#section4">section4</a></li>
</div>

<a id="section1">SECTION 1</a>
<p>Here is some dummy text for section 1.</p>

<a id="section2">SECTION 2</a>
<p>More dummy text for section 2.</p>

<a id="section3">SECTION 3</a>
<p>Additional dummy text for section 3.</p>

<a id="section4">SECTION 4</a>
<p>Extra dummy text for section 4.</p>

Answer №1

To achieve this functionality, you can utilize a foreach loop within the <li> tag in your code. This way, every time a user clicks on an item in the menu, the script will remove the 'open' class from the menu.

const menuBtn = document.querySelector('.menu-btn');
let menuOpen = false;
menuBtn.addEventListener('click', () => {
  if (!menuOpen) {
    menuBtn.classList.add('open');
    document.getElementById("mymobilemenu").style.display = "block";
    menuOpen = true;
  } else {
    menuBtn.classList.remove('open');
    document.getElementById("mymobilemenu").style.display = "none";
    menuOpen = false;
  }
});
let menuli = document.querySelectorAll('#mymobilemenu li');
menuli.forEach((item, index) => {
 item.addEventListener('click', () => {
 menuBtn.classList.remove('open');
    document.getElementById("mymobilemenu").style.display = "none";
    menuOpen = false;

});

});
.menu-btn {
  position: relative;
  float: right;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80px;
  height: 80px;
  cursor: pointer;
  transition: all .5s ease-in-out;
  border: 3px solid blueviolet;
  background: pink;
}

.menu-btn-burger {
  width: 50px;
  height: 6px;
  background: yellow;
  border-radius: 5px;
  transition: all .5s ease-in-out;
}

.menu-btn-burger::before,
.menu-btn-burger::after {
  content: '';
  position: absolute;
  width: 50px;
  height: 6px;
  background: grey;
  border-radius: 5px;
  transition: all .5s ease-in-out;
}

.menu-btn-burger::before {
  transform: translateY(-16px);
}

.menu-btn-burger::after {
  transform: translateY(16px);
}


/* animation of burger */

.menu-btn.open .menu-btn-burger {
  transform: translateX(-50px);
  background: transparent;
  box-shadow: none;
}

.menu-btn.open .menu-btn-burger::before {
  transform: rotate(45deg) translate(35px, -35px);
}

.menu-btn.open .menu-btn-burger::after {
  transform: rotate(-45deg) translate(35px, 35px);
}

#mymobilemenu {
  display: none;
}
<div class="menu-btn">
  <div class="menu-btn-burger">
  </div>
</div>

<div id="mymobilemenu">
  <li><a href="#section1">section1</a></li>
  <li><a href="#section2">section2</a></li>
  <li><a href="#section3">section3</a></li>
  <li><a href="#section4">section4</a></li>
</div>

<a id="section1">SECTION 1</a>
<p>Lorem Ipsum is simply dummy text...

Answer №2

Here is a suggestion for your JavaScript script implementation:

const elements = document.querySelectorAll('.elements');
elements.forEach(item => {
  item.addEventListener('click', () => {
    button.classList.remove('active');
    document.getElementById("mobile-nav").style.display = "none";
    console.log("Element removed from view");
  })

});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Change wiki text into HTML using Python for showcasing on a webpage

Despite trying various tools for 6 hours, I have been unable to find one that can properly interpret wikitext like the example below: '<center>Welcome to the world's foremost open content<br><big><big><big>'&ap ...

Is it possible for one div to prompt an ajax response in another div?

In my attempt to create a main page with 3 div sections, I am using ajax to sequentially load content into each area. The idea is to have div1 already loading the page fetched from ajax as soon as the main page loads. This includes heavy mysql operations o ...

The HTML table printout is missing cells in the first column

Encountered a strange issue with Internet Explorer and Chrome involving a basic HTML table. The table has no layout CSS, 2 columns, no styles, and its width is set to 100%. When attempting to print the table in these browsers, the first cell on the second ...

Utilizing Jquery to create a carousel with looping functionality for flowing text

I am currently facing an issue with a carousel that contains multiple images and text. In order to make the text responsive, I have implemented a script called FlowText. The script works perfectly on the initial carousel image (the active one), but as soon ...

Tips for utilizing the onload attribute alongside the ng-controller directive to run a function that has been established within the controller

When trying to call the submit() function as soon as the page loads, I keep encountering a submit() method not found error. The positioning of ng-controller and onload is confusing to me. If there is an alternate method in Angular to achieve this, please ...

Enhancing Javascript with ES6 for nested for loop operations

Hey there, I have a question about converting a nested for loop into an Array map/ES6 way. How does that work when dealing with nested for loops? for (var i = 0; i < enemy.ships.length; i++) { for (var n = 0; n < enemy.ships[i].locat ...

Tips for enabling animation for AmCharts animateData feature

To achieve a real-time values per minute chart, the last bar value is to be incremented every minute after its addition. Additionally, a new bar with a value of 1 will be added each minute while removing the oldest bar. All these changes need to be animat ...

Validating properties of a class using Typescript's Class-Validator

I tried using the class-validator decorator library for validation processes on my sample project. However, it doesn't seem to be working as expected. The sample project aims to create projects based on user inputs, and I'm attempting to validate ...

Adjusting position in relation to the cursor's movements

I have searched extensively for similar questions but have been unable to resolve my issue. Here, I am sharing just a single list item from my code. The task at hand is to create a span element on the mousemove event over the list item, and dynamically set ...

Stopping the use of <script> tags within HTML form submissions

After launching my website at , I discovered that a user is attempting to redirect it to different websites using HTML form input tags. While I'm unsure of the exact method they are employing, I am seeking a way to block users from entering these nefa ...

Update the objects with new values when the user makes changes in the

I am working with dynamically created input fields const [data, setData] = useState({ native: [{}], rolls: [{}] }) // initial data {navtive?.map((item, index) => { return ( <input type="text" name={item.id} ...

Instructions on finding and inputting text into a textarea using python and javascript

Hello there, I've been experimenting with writing text inside a textarea element using Python Selenium and JavaScript: The JavaScript code I'm using is: self.driver.execute_script("document.getElementsByClassName('textarea').value ...

What is the process for implementing a grid with 5 columns on larger screens and 2 columns on smaller screens using reactjs?

I am currently working on building a Grid using material UI and reactJs. I found the guidelines on this link https://mui.com/system/react-grid/. However, there seems to be an issue with creating 5 columns in the grid. I attempted to create a custom grid ...

What is the best way to align bootstrap grid columns perfectly centered beneath a set of three columns?

I'm attempting to create a container grid layout similar to the one shown below using Bootstrap 4. The layout consists of three evenly spaced boxes at the top, followed by two additional boxes centered and evenly spaced below them: https://i.sstatic. ...

I have written code in JavaScript, but now I am interested in converting it to jQuery

What is the best way to convert this to jQuery? showDish("balkandish1") function showDish(dishName) { var i; $(".city").css('display', 'none'); $("#" + dishName).css('display', 'block'); } ...

Divide HTML content while keeping inner tags intact

Currently, I am developing an online store. In my code, there is a requirement to display attributes and descriptions for multiple products on a single page. The attributes are displayed in a table format, while the description can include simple text as w ...

Why am I unable to insert data into the 'sessions' database using connect-mongo?

I am utilizing connect-mongo in conjunction with express-session, and the session data is successfully being stored in Mongo. However, I want to enhance the sessions collection utilized by connect-mongo in order to include my own fields on top of it. I h ...

Utilize Node.js to encrypt data from an extensive file

Hello, this is my initial inquiry. English isn't my native language and I need some help. I have a large file with about 800K lines that I need to read and encrypt using the sjcl library. So far, I've only managed to write the following code snip ...

Managing Events in PHP

As a .net developer working on a php site for a friend, I've been making good progress. However, I have a question - is there something similar to a textchanged event in php? Here's what I'm trying to achieve: I want to dynamically populate ...

Change to the parent frame using webdriver

I am facing an issue while trying to switch to the parent frame or iFrame using webdriver.js. Although I have implemented a function that works, it only goes up to the second level of frames. When attempting to switch to the parent frame from a deeper fr ...