How can I automatically close the side menu when clicking on one of its list items?

I found inspiration for my project from this example http://tympanus.net/codrops/2014/09/16/off-canvas-menu-effects/. Specifically, I've been using the Elastic example. Everything is working well, and the menu closes when clicking outside of the menu body. However, I'm looking to implement a feature where clicking on one of the subitems will not only scroll the page to a specific section (e.g., "Living Room" scrolls to #livingroom) but also close the side menu after scrolling. Here's the structure of my menu-

<div class="menu-wrap">
            <nav class="menu">
                <div class="icon-list">
                <br>
                  <a href="#"><i class="fa fa-fw fa-home"></i><span>HOME</span></a>
                  <a href="#" id="btn-1"  data-toggle="collapse" data-target="#submenu0" aria-expanded="false"><i class="fa fa-fw fa-building"></i><span>PLACES</span></a>

                     <ul class="nav collapse" id="submenu0" role="menu" aria-labelledby="btn-1">
                            <li class="page-scroll"><a href="#livingroom" style="margin:0 30px;text-decoration:none;"><p style="font-weight:1em;font-size:14px;">Living Room</p></a></li>
                            <li class="page-scroll"><a href="#bedroom" style="margin: 0 30px;"><p style="font-weight:1em;font-size:14px;">Bed Room</p></a></li>

                     </ul>


                      <a href="#" id="btn-2" style="text-decoration:none;" data-toggle="collapse" data-target="#submenu1" aria-expanded="false"><i class="fa fa-fw fa-compress"></i><span>NFC</span></a>
                      <ul class="nav collapse" id="submenu1" role="menu" aria-labelledby="btn-2" >
                            <li><a href="#0" style="margin:0 30px;text-decoration:none;"><p style="font-weight:1em;font-size:14px;">Read NFC Tag</p></a></li>
                            <li><a href="#0" style="margin: 0 30px;"><p style="font-weight:1em;font-size:14px;">Write to NFC Tag</p></a></li>

                      </ul>

                    <a href="#"><i class="fa fa-fw fa-cogs"></i><span>SETTINGS</span></a>
                    <a href="#"><i class="fa fa-fw s fa-align-justify"></i><span>ABOUT</span></a>
                    <a href="#"><i class="fa fa-fw s fa-bookmark-o"></i><span>REFERENCES</span></a>
                </div>
            </nav>
            <button class="close-button" id="close-button">Close Menu</button>
            <div class="morph-shape" id="morph-shape" data-morph-open="M-1,0h101c0,0,0-1,0,395c0,404,0,405,0,405H-1V0z">
                <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 100 800"
                preserveAspectRatio="none">
                    <path d="M-1,0h101c0,0-97.833,153.603-97.833,396.167C2.167,627.579,100,800,100,800H-1V0z"></path>
                </svg>
            </div>
        </div>

Here's the JavaScript part-

            (function() {
            var bodyEl = document.body,
                    content = document.querySelector( '.content-wrap,.menu' ),
                    openbtn = document.getElementById( 'open-button' ),
                    closebtn = document.getElementById( 'close-button' ),
                    isOpen = false,

                    morphEl = document.getElementById( 'morph-shape' ),
                    s = Snap( morphEl.querySelector( 'svg' ) );
                    path = s.select( 'path' );
                    initialPath = this.path.attr('d'),
                    pathOpen = morphEl.getAttribute( 'data-morph-open' ),
                    isAnimating = false;

                function init() {
                    initEvents();
                }

                function initEvents() {
                    openbtn.addEventListener( 'click', toggleMenu );
                    if( closebtn ) {
                        closebtn.addEventListener( 'click', toggleMenu );
                    }

                    // Close the menu element if the target is not the menu itself or one of its descendants..
                    content.addEventListener( 'click', function(ev) {
                        var target = ev.target;
                        if( isOpen && target !== openbtn ) {
                            toggleMenu();
                        }
                    } );
                }

                function toggleMenu() {
                    if( isAnimating ) return false;
                    isAnimating = true;
                    if( isOpen ) {
                        classie.remove( bodyEl, 'show-menu' );
                        // Animate path
                        setTimeout( function() {
                            // Reset path
                            path.attr( 'd', initialPath );
                            isAnimating = false; 
                        }, 300 );
                    }
                    else {
                        classie.add( bodyEl, 'show-menu' );
                        // Animate path
                        path.animate( { 'path' : pathOpen }, 400, mina.easeinout, function() { isAnimating = false; } );
                    }
                    isOpen = !isOpen;
                }

                init();
            })();

Thank you in advance.

Answer №1

By examining the code at http://tympanus.net/Development/OffCanvasMenuEffects/js/main4.js, it becomes clear that the close menu icon triggers the toggleMenu function.

if( closebtn ) {
        closebtn.addEventListener( 'click', toggleMenu );
}

To enable the toggleMenu function when clicking on a sub item, simply add a click event to trigger it.

Answer №2

Incorporating .icon-list a into the variable below should successfully achieve the desired outcome:

container = document.querySelector( '.wrapper,.menu-list' ),

Here's how you can implement it:

container = document.querySelector( '.wrapper,.menu-list,.icon-list a' ),

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

Transfer data from a selection list in an HTML document to a Google Apps Script function and then dynamically update another selection

I am using a Google Web App to fetch text data from a spreadsheet based on dropdown selections. I want the options in the "Grade" dropdown list to be dynamic, changing according to the selection made in the "Role" dropdown menu. My approach involves using ...

How can I change the orientation of a cube using d3js?

Seeking guidance on creating an accurate chart using d3js How can I rotate the SVG to display the opposite angle as shown in the image? Any recommended resources for achieving this desired result would be greatly appreciated. The provided code only disp ...

Ways to include text with specific choices in a drop-down menu?

Within a form, I am encountering a situation where a select box's options are pre-selected through ajax based on a previously entered value. I am now seeking a way to append additional text to these pre-selected options only. for (i in data) { $("#my ...

Clearing the view state of a specific repeater control

There is a specific requirement that I must fulfill, which involves deleting the view state of a particular repeater using jQuery or JavaScript. For instance, suppose I have two repeaters: repeater 1 and repeater 2. Upon clicking a button, I would like to ...

The router is unable to direct when an item is clicked

I am encountering an issue with my routing setup - when I click on an item in the list-item component, it does not successfully route to the detail-component. Here is a glimpse of my source code: product-list.component.html: <h1>Product List Compon ...

I am experiencing an issue with applying responsiveFontSize() to the new variants in Material UI Typography

I am looking to enhance the subtitles in MUI Typography by adding new variants using Typescript, as outlined in the documentation here. I have defined these new variants in a file named global.d.ts, alongside other customizations: // global.d.ts import * a ...

Error Message in Angular 6 When Importing JQVMap - No Such 'vectorMap' Property on Type 'JQuery<HTMLElement>'

I'm currently facing some challenges trying to integrate a clickable map, JQVMap and JQuery into my Angular 6 project. Issue: error TS2339: Property 'vectorMap' does not exist on type 'JQuery'. Here is the component in question: ...

Regular Expression - Locating the nth Instance - examining web page source information

My query is as follows: (?<=>)(\w*)(?=<) This code extracts all the words between the angle brackets > and <. However, I am only interested in capturing the third occurrence. I have experimented with various placements of {2} within ...

Update the class information using jQuery after performing an action and serialize the button's ID for AJAX requests

I'm facing an issue with two buttons on my page: <td> <button id="1" class="green-button">Publish</button> <button id="1" class="yellow-button">Delete</button> </td> The green-button and red-button have different ...

When attempting to remove an object from the scene, an error occurs stating that children[i]

Is there a way to remove an object from the scene? removeObjectFromScene = (position) => { this.scene.traverse((child) => { if (child.isGroup && child.userData.position) { if (child.userData.position.equals(position)) ...

Step by step guide on including a JavaScript function in a web worker using importScripts

I am encountering an issue with my worker.js file: self.importScripts('/static/utils/utils.js') onmessage = (e) => { let a = e.data[0] let b = e.data[1] let c = func1(a,b) postMessage(c) } The structure of the utils.js file ...

How can one identify a concealed glitch that exclusively occurs for a particular individual or hardware in a React environment?

Is it possible to identify a bug that occurs only with a particular individual or hardware in a React application? This bug is invisible and never appears during tests, but only manifests with a specific client within my company. Do you have any tips on h ...

I have a json file that I need to convert to a csv format

I am currently working with a json file, but I need to switch it out for a csv file. Do I have to use a specific library to accomplish this task, or can I simply modify the jQuery 'get' request from json to csv? I attempted the latter approach, b ...

Storing and Manipulating a JavaScript Object with Vuex: A New Perspective

Consider a hypothetical JavaScript object class like this: class Car { var engineTurnedOn = false; ... public turnEngineOn() { engineTurnedOn = true } } If I want to turn the engine on, should I create an action called 'turnEngineOn&ap ...

Is there a way to create a color bar that is positioned halfway below the title using only CSS? I am looking to only color the lower half of a div - can this be achieved

Is there a way to create a color bar beneath the title using only HTML and CSS without relying on background images? I want the bar to be flush with the text and have some flexibility in terms of width to prevent wrapping. Alternatively, can you position ...

Incorporate a collection of multiple images into Fancybox

Can someone help me figure out how to use fancybox to display a series of images in a lightbox? I have this JS object called fancybox_img, and here's what it contains: {card_173: Array(1), card_171: Array(5), card_169: Array(4)} card_169: Array(4) 0: ...

What is the best way to calculate checksum and convert it to a 64-bit value using Javascript for handling extremely large files to avoid RAM overflow?

Question: What is the best method for generating a unique and consistent checksum across all browsers? Additionally, how can a SHA256/MD5 checksum string be converted to 64-bit? How can files be read without requiring excessive amounts of RAM when ...

Ways to eliminate a value once a checkbox is deselected

I am currently developing a search box that includes three separate fields which will be populated with data using AJAX based on the user's selection. Here is the HTML structure I have implemented: <div id="states"> <input type="checkbo ...

Issue with Laravel Blade: HTML elements are not being displayed in my blade template file

After implementing WYSIWYG fields in my form, I noticed that the html tags are not being properly rendered upon retrieving the data. The HTML tags still appear in their raw form within the form itself. Attempting solutions found on this thread, I believed ...

Daniel Opitz explores the best placement for DataTables within the slim4 framework

After purchasing Daniel Opitz's eBooks, I found myself on page 226 trying to implement data tables in my project. The books mention: DataTables Setup DataTables.net is a very flexible table plug-in for jQuery. You have to setup jQuery for Webpack firs ...