What is the best way to utilize a single button to both open and close my burger menu?

Having just started learning javascript, I've encountered a problem that has me stuck.

I recently stumbled upon a code snippet on W3 schools for creating an animated burger menu, which I thought was pretty cool. I successfully linked it to my side menu and got it to open up when clicked; however, the same button wouldn't close the menu.

To link my side menu, I added ;openSlideMenu() to the onclick function in the first div container.

My attempts to add a closing feature with ;closeSlideMenu() in the same container were unsuccessful. I believe this is because the name of the div container "burger-menu-btn" changes to "burger-menu-btn change" when clicked, as instructed by the toggle function.

<!-- Burger menu icon and animation -->
    <div class="burger-menu-btn" onclick="myFunction(this); openSlideMenu();">
        <div class="burger-menu-bar-1"></div>
        <div class="burger-menu-bar-2"></div>
        <div class="burger-menu-bar-3"></div>
    </div>

    <script>
        function myFunction(x) {
            x.classList.toggle("change");
        }

        function openSlideMenu(){
            document.getElementById('burger-menu').style.width = '100%';
        }

        function closeSlideMenu(){
            document.getElementById('burger-menu').style.width = '0px';
        }
    </script>

    <div id="burger-menu" class="side-nav">
        <a href="index.html">Home</a>
        <a href="cases.html">Basic // GF2 </a>
        <a href="#">Null</a>
        <a href="#" >Null</a>
        <a href="#">Null</a>
        <a href="#" class="btn-close" onclick="closeSlideMenu()">&times;</a> 
    </div>  

My main objective is:

To have the red "burger-menu-btn" open the slider "burger-menu", which it currently does.

and then have the transformed X close the same slider menu.

This way, I'll have a stylish, animated burger menu without needing the small makeshift "btn-close" button at the bottom of my navigation bar.

Fiddle link: https://jsfiddle.net/02rqy16f/

Thank you in advance for any help or advice; I apologize if I overlooked any key details.

Answer №1

when you click on the same button, both the opening and closing actions are performed for the menu. Here is how you can toggle the menu:

<div class="burger-menu-btn" onclick="myFunction(this); toogleSlideMenu(this);">
    <div class="burger-menu-bar-1"></div>
    <div class="burger-menu-bar-2"></div>
    <div class="burger-menu-bar-3"></div>
</div>

<script>
    function myFunction(x) {
        x.classList.toggle("change");
    }

    function toogleSlideMenu(x){
       if(x.classList.contains('change')){
          document.getElementById('burger-menu').style.width = '100%';
       }
       else{
          document.getElementById('burger-menu').style.width = '0px';
       }
    }

</script>

https://jsfiddle.net/esa1vn0j/1/

Answer №2

Implementing your suggested method (where the width is defined), I would suggest creating a unified function called toggleSideMenu with the following logic:

  • Check whether the element's width is currently set to 100%.
  • If not, change it to 100%.
  • Otherwise, adjust it to 0px.

Illustration:

<!-- Icon for burger menu and its animation -->
<div class="burger-menu-btn" onclick="toggleSideMenu(this);">
  <div class="burger-menu-bar-1"></div>
  <div class="burger-menu-bar-2"></div>
  <div class="burger-menu-bar-3"></div>
</div>

<script>
  function toggleSideMenu(x) {
    const el = document.getElementById('burger-menu')
    el.style.width = el.style.width === '100%' ? '0px' : '100%'
  }
</script>

<div id="burger-menu" class="side-nav">
  <a href="index.html">Home</a>
  <a href="cases.html">Basic // GF2 </a>
  <a href="#">Null</a>
  <a href="#" >Null</a>
  <a href="#">Null</a>
  <!--  "btn-close" here is my old way of closing this menu, i am not happy with it at all.
  which is why i want to close this menu, with the same button that opens it above-->
  <a href="#" class="btn-close" onclick="closeSlideMenu()">&times;</a> 
</div>  

In reality, using a class like .opened would be the simpler solution for toggling purposes.

Answer №3

If you want to change the width of the "#burger-menu" element when clicking on the burger icon, you can achieve this by toggling a class (for example, "open") and then setting the width of "#burger-menu" in the CSS.

#burger-menu{
  width: 0%;
}
#burger-menu.open{
  width: 100%;
}

Here is the click function:

document.getElementById('burger-menu').classList.toggle("open");

Check out the demo here.

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

How come the HTML page served by the express.js route isn't linked to a CSS stylesheet?

Recently, I've been working with a server.js file that imports a router const path = require("path"); const express = require("express"); const app = express(); const PORT = 8080; app.use(express.urlencoded({ extended: true })); app.use(express.jso ...

Passing data back from an asynchronous function to its parent function in Node.js

Exploring the world of asynchronous programming is a new adventure for me as I delve into implementing Twilio video calls through Node.js. I've been grappling with calling a server-side function that in turn invokes another asynchronous function retu ...

Encountered an unexpected token '{' error in Discord.js and Node.js integration

let user = message.mentions.users.first(); if (message.mentions.users.size < 1) return message.reply('Please mention someone to issue ARs.').catch(console.error); mcash[${user.id}, ${message.guild.id}].mc ...

How can I include a JSON object in an angularjs $scope variable?

How can I effectively inject my JSON Object into my angular $scope during the create() function? Sample HTML: <input type="text" class="title" placeholder="hold" ng-model="formData.text"/> <input type="text" class="desc" placeholder="description ...

Improve the functionality of select[multiple] to allow for single-click modifications without the need for CMD/CTRL

I am attempting to modify the default functionality of a select element so that clicking once on its options changes their selected state. Essentially, I want to eliminate the confusing requirement of holding down shift/ctrl to select multiple options. I ...

Creating a code script for the purpose of automating npm commands

Currently, I am immersed in an angular js project and I have a desire to streamline the execution of the following two commands. ./node_modules/protractor/bin/webdriver-manager update ./node_modules/protractor/bin/webdriver-manager start The challenge li ...

Is it possible for me to reconstruct the "reducer" each time the useReducer hook is rendered?

Here is an example taken from: https://reactjs.org/docs/hooks-reference.html#usereducer const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; ...

Dealing with the error "Type 'date[]' is not assignable to type '[date?, date?]' in a React hook

I'm attempting to assign a date range but encountering an error that states: Type 'Date[]' is not assignable to type '[Date?, Date?]'. Types of property 'length' are incompatible. Type 'number' is not assignab ...

Missing data or unknown value

Hey, I'm currently experiencing an issue while trying to add a new post to my database. It keeps saying that all the values are undefined. <form action="/add-nova-uc" method="POST"> <div class="formulario" cl ...

The Google Maps display for this page failed to load properly on the map

<!-- <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script> --> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initialize" async="" defer="defer" type="text/javascript">& ...

What methods can be used to adjust the dimensions of a webpage's textbox?

I've been working on a Chrome extension and I have encountered a few challenges that I need help with. One issue I'm facing is changing the size of the text box in the Facebook chat box at the right bottom corner of the page. To accomplish this ...

Easily done! Using JavaScript to generate a blinking cursor on a table

Working on a project to develop a dynamic version of the classic game Tic-Tac-Toe... However... Every table cell is displaying an irritating flashing cursor, almost like it's behaving as an input field. Any insights into why this is happening...? O ...

Is it possible to deploy a build across various website subdomains without altering user data?

Currently, I am in the midst of developing a project for a client where I am responsible for both the front end and back end components. After much consideration, I have opted to use Remix due to my familiarity with React and proficiency in JavaScript/Type ...

Is it considered poor form to send as many as 100 ajax requests when loading a webpage?

My table can display up to 100 rows, sometimes even more. Is it considered a bad practice to loop through all these rows and send an AJAX post request to fetch data? I am hesitant to do this during the page load as it may significantly slow down the loadin ...

I encountered an issue while operating my next.js application which utilizes solidity smart contracts. The error message "Cannot read properties of undefined" was displayed during the process

While working on my next.js app and attempting to fetch user data, I encountered the "cannot read properties of undefined" error. https://i.stack.imgur.com/SBPBf.png I also received the following error in the console https://i.stack.imgur.com/JBtbO.png ...

Error: Invalid character encountered during login script JSON parsing

I found this script online and have been experimenting with it. However, I encountered the following error: SyntaxError: JSON.parse: unexpected character [Break On This Error] var res = JSON.parse(result); The problem lies in the file below as I am unf ...

Retrieve the initial element of a JavaScript array

Is there a way to retrieve the first element of a JavaScript array without using array[0]? Interestingly, the array being passed into the method seems to have its first (and only) element stored at index 5 instead of 0. Update - I've attempted to cr ...

Received net::ERR_EMPTY_RESPONSE error when making an AngularJs POST request

My specific header request Request URL:http://demo7876167.mockable.io/auth/login Request Headers Provisional headers are shown Access-Control-Request-Headers:accept, content-type Access-Control-Request-Method:POST Origin:http://localhost:8000 Referer:http ...

What sets Fetch apart from ajax and XMLHttpRequest that makes it impressively faster?

Over the past few days, I have been working on optimizing a client table for a project. The table contains over 10k clients, and as a result, it was taking a long time to load. The front-end team had implemented pagination, filters, and reordering, which ...

Encountering an issue while trying to launch an Angular application on localhost. Vendor.js resource failed to load

Whenever I compile the code, it runs successfully. However, when I try to serve the application using 'node --max-old-space-size=8192', even though it compiles without any errors, when I open the app in a browser, it returns an error saying "Cann ...