Issue with JQuery where the click event is not functioning properly after resizing

I'm currently working on a responsive menu that dynamically adjusts based on the window's width. When the browser is resized to fit the minimum width, a click function for a button is enabled; otherwise, the click function is disabled. This setup is necessary because the same element serves as both a button on the mobile version and a visual element on the desktop version.

The issue I'm facing is that, with my current code, the click function works fine when the page loads, whether on a desktop or mobile screen. However, if I resize the browser and try to click the element again, it doesn't work. To make the mobile navigation function properly, I need to refresh the page every time, which can be quite frustrating.

To better illustrate the problem, I've created a simple example with the following code (just to demonstrate the click function issue)

HTML

<!-- WRAPPER -->
<div id="freakers-wrapper">
    <!-- HEADER -->
    <header id="header">
        <div class="header-bottom">
            <div class="container">
                <div class="row">
                    <div class="col-md-5">
                        <!-- MENU -->
                        <nav class="menu-wrapper-left">
                            <a class="menu-trigger" href="#">
                                <span></span>
                            </a>

                            <ul id="main-menu" class="menu menu--main menu--left main-menu">
                                <li><a href="#">Home</a></li>

                                <li class="has-children">
                                    <a href="#">Shop</a>

                                    <ul class="sub-menu is-hidden">
                                        <li class="go-back"><a href="#">Back</a></li>
                                        <li><a href="#">Shop 1</a></li>
                                        <li><a href="#">Shop 2</a></li>
                                        <li><a href="#">Shop 3</a></li>
                                    </ul>
                                </li>
                                <li><a href="#" >Blog</a></li>
                            </ul>   <!-- end main-menu -->
                        </nav>  <!-- end menu-wrapper -->
                    </div>

                    <div class="col-md-2">
                        <div class="logo">
                            <a href="#">
                                <img src="images/logo.png" alt="Logo" class="img-responsive">
                            </a>
                        </div>
                    </div>

                    <div class="col-md-5">
                        <!-- MENU -->
                        <nav class="menu-wrapper-right">
                            <ul id="main-menu" class="menu menu--main menu--right main-menu">
                                <li><a href="#">help</a></li>
                                <li><a href="#">lookbook</a></li>
                                <li><a href="#">model</a></li>
                            </ul>   <!-- end main-menu -->
                        </nav>  <!-- end menu-wrapper -->
                    </div>
                </div>
            </div>
        </div>  <!-- end header-bottom -->
    </header>   <!-- end header -->

    <!-- MOBILE NAV -->
    <div id="mobile-nav"></div>
</div>  <!-- end freakers-wrapper -->

JS

(function($) {
    "use strict";

    $(document).ready(function () {

        $(window).on('load resize', function(){
            moveNavigation();
        });

        /* ----------------------------------------------------------------------
            Main Menu
        ---------------------------------------------------------------------- */

        //if you change this breakpoint, don't forget to update this value as well
        var MqL = 1030,
            menuLeft = $('.menu-wrapper-left').html(),
            menuRight = $('.menu-wrapper-right').html();
            console.log(menuRight);
            console.log(menuLeft);
        //move nav element position according to window width
        // moveNavigation();

        //mobile - open lateral menu clicking on the menu icon
        $(document).on('click', '.menu-trigger', function(event){
            event.preventDefault();
            if($('#freakers-wrapper').hasClass('push-content')){
                closeNav();
            }else{
                $('#freakers-wrapper').addClass('push-content');
                $('#mobile-nav .menu').addClass('menu--open');
                $(this).addClass('nav-is-visible');
            }
        });

        //open submenu
        $('.has-children').on('click', function(event){
            var selected = $(this);
            if( selected.children('ul').hasClass('is-hidden') ) {
                selected.children('ul').removeClass('is-hidden');
            }
        });

        //submenu items - go back link
        $('.go-back').on('click', function(evt){
            evt.stopPropagation();
            $(this).parent('ul')
                .addClass('is-hidden')
                .parent('.has-children')
                .parent('ul');
        });

        function closeNav(){
            $('#freakers-wrapper').removeClass('push-content');
            $('.menu--main').removeClass('menu--open');
            $('.has-children ul').addClass('is-hidden');
        }

        function checkWindowWidth() {
            //check window width (scrollbar included)
            var e = window, 
                a = 'inner';
            if (!('innerWidth' in window )) {
                a = 'client';
                e = document.documentElement || document.body;
            }
            if ( e[ a+'Width' ] >= MqL ){
                closeNav();

                if ( $('.menu-trigger').hasClass('menu-trigger-open') ){
                    $('.menu-trigger').removeClass('menu-trigger-open');
                }
                return true;
            } else {

                var menuElm = $('.main-menu .has-children');

                if($('.sub-menu ul', menuElm).hasClass('left-menu')){
                    $('.sub-menu ul', menuElm).removeClass('left-menu');
                }
                return false;
            }
        }

        function moveNavigation(){
            var navigation = $('.menu--main'),
                desktop = checkWindowWidth();

            if ( desktop ) {
                $('#mobile-nav').children().remove();
                $('.menu-wrapper-left').html(menuLeft);
                $('.menu-wrapper-right').html(menuRight);
            } else {
                navigation.appendTo('#mobile-nav');
                $('.menu--main').not(':first').remove().children('li').appendTo('.menu--main:first');
            }
        }

        $(".menu-trigger").click(function() {
            $(this).toggleClass("menu-trigger-open");
        });
    });
}(jQuery));

If you wish to see this example live, I have created a Codepen demo where you can resize the window to observe the functionality

http://codepen.io/thehung1724/full/JYmzWr/

I hope I have adequately explained the issue I am facing. I have searched extensively but could not find a solution to this problem. Any assistance or guidance would be greatly appreciated!

Answer №1

A simple solution would be to substitute

$('.has-children').on('click', function(event){

with

$(document).on('click', '.has-children', function (event) {

When you move the navigation from one place to another, the link to the on-click function for .has-children is lost.

By using $(document).on..., you are binding the function to the document, which prevents it from being disposed of.


Update: Replace this section of JavaScript code

        $('.has-children').on('click', function (event) {
            var selected = $(this);
            if (selected.children('ul').hasClass('is-hidden')) {
                selected.children('ul').removeClass('is-hidden');
            }
        });
        $('.go-back').on('click', function (evt) {
            evt.stopPropagation();
            $(this).parent('ul').addClass('is-hidden').parent('.has-children').parent('ul');
        });

With

    $(document).on('click', '.has-children', function (event) {
        var selected = $(this);
        if (selected.children('ul').hasClass('is-hidden')) {
            selected.children('ul').removeClass('is-hidden');
        }
    });
    $(document).on('click', '.go-back', function (evt) {
        evt.stopPropagation();
        $(this).parent('ul').addClass('is-hidden').parent('.has-children').parent('ul');
    });

Further update: I have made modifications to your code in CodePen with the above changes: http://codepen.io/anon/pen/JYmVXm

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

Error encountered while parsing Node.js code for MySQL query execution

I am encountering an error message from Node that reads: Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TIMESTAMPDIFF(second, entered_at, c ...

What is the best way to target the shadow DOM host element specifically when it is the last child in the selection?

I want to style the shadow DOM host element as the last child. In this particular situation, they are currently all green. I would like them to be all red, with the exception of the final one. class MyCustomElement extends HTMLElement { constructor() ...

What is the best way to adjust the size of an IMG element while ensuring it remains proportionate and in the same position when the window size is altered?

I am currently in the process of developing a GPS-inspired application, and I have encountered a roadblock while attempting to establish 'no-go' zones on the map. My goal is to have the map dynamically resize based on the window dimensions, using ...

What is the best way to move between websites or pages without having to reload the current page using a selector?

Have you ever wondered how to create a webpage where users can navigate to other websites or pages without seeing their address, simply by selecting from a drop-down menu? Take a look at this example. Another similar example can be found here. When visit ...

Converting a collection of div elements into a JavaScript array without using jQuery

Is there a way to transform a list of HTML divs into a JavaScript array? Below is the snippet of HTML code: <div class="colors"> <div>Red</div> <div>Blue</div> <div>Orange</div> <div>Green< ...

Experimenting with alterations to link styles

A particular test we are conducting involves examining the style changes of a link (a element) after a mouse over. Initially, the link is displayed with a black font and no decoration. However, upon hovering the mouse over it, the font color changes to bl ...

What is the proper method for utilizing the finished callback function in NativeScript TextToSpeech?

Is there a way to sequence nativescript text-to-speech messages and use a callback function? How can the finished callback function be utilized? The SpeakOptions in nativescript-texttospeech include a finishedCallback property. I want the TTS to read te ...

Receive the innerHTML of an Element after appending additional Elements - Selenium

When working with my table in HTML, I have noticed that the <td> tag can be accessed in two different ways: 1. <td><font size="4" face="Arial"><i>Google</i></font></td> 2. <td>Google</td> I am curr ...

JS Implementation of the Coin Change Algorithm

I've been grappling with this algorithm for the past few days, but unfortunately I haven't been able to come up with a successful solution yet. The available solutions seem to be too advanced for my current level of understanding. This problem mu ...

Creating custom shaders in three.js that can receive shadows involves a few key steps. Let

For more information, you can visit the original post here. The task at hand seems to be quite complex due to the lack of documentation and examples on this specific topic on the three.js website. Currently, I am able to render the correct image and, with ...

Using v-model in a child component and setting v-model within a child component in a Vue project

How can I simplify this code? Ensure that the button also updates the localValue of the child component. Vue.component('my-input', { template: ` <div> <b>My Input:</b> <br> localValue: {{ localValue } ...

Looking for assistance in creating a unique jQuery validation function tailored to your

Looking at my form attribute, it appears as follows: onsubmit="return validateForm(this);" Additionally, I have a jQuery function set up like this: function validateForm(form) { $(form,"input").each(function() { if($(this).length < 1) { ...

Tips for sending multiple values to the next page using AngularJS

Hey there, I'm new to AngularJS and currently using Onsen UI in my demo application. I have two pages in my app and I'm trying to pass two values to the next page. I managed to pass one value successfully, but when I attempt to send the second on ...

Tips for adjusting the time format within Ionic 3 using TypeScript

I currently have a time displayed as 15:12:00 (HH:MM:SS) format. I am looking to convert this into the (3.12 PM) format. <p class="headings" display-format="HH:mm" > <b>Time :</b> {{this.starttime}} </p> In my TypeScript code t ...

Adjust the size of the inputs within a Bootstrap form-inline

How can I adjust the input size in Bootstrap 3 to fit my nav-bar properly? I attempted the following: <label class="col-sm-2 sr-only" for=”email">Email address</label> Unfortunately, it did not have the desired effect. I also tried: < ...

Error: Unable to perform the function 'push' on 'data' as it is

I am attempting to add new data info.push({"country": "IN"}); to a JSON string as a new identifier and value. Unfortunately, I encounter the following error: Uncaught TypeError: info.push is not a function data{"name":"ananta","age":"15"} Thank you in ...

Tips for maintaining the data type of a typed array in typescript while clearing it?

During a recent class, I defined an array with the type CustomType as shown below: class Example { public exampleArray: CustomType[]; public clearArray() { this.exampleArray = []; } } It appears that the clearArray method assigns an UNDEFINED t ...

I recently ran npm install --save bootstrap and now I am unable to locate the bootstrap.min.css file anywhere

Trying to follow a tutorial based on a video, I'm running into an issue where I can't locate the bootstrap.min.css file mentioned. Despite searching online, I haven't found any relevant information. The files I have access to are: https://i ...

Accessing JSON data through crawling may trigger an "Invalid access" warning

Currently extracting data, I came across this base URL After inspecting chrome's developer tools - Network tab, I found the following URL: international?Adt=1&Chd=0&ECITY1=HKG&ECITY2=ICN&Fa…019.03.13.&TRIP=RT&W ...