Having trouble toggling the navbar on and off in mobile. Error message: Unable to read parentnode of undefined

When I try to make my mobile navbar full screen on a mobile device, the hamburger button works as expected when clicked. Initially, all the links are displayed in full page view, but once I click on a link, it disappears and takes me to the respective section of the page. However, the issue arises when I try to do two consecutive clicks – an error saying “Cannot read property parentNode of undefined” is thrown. It seems like the problem lies in how I am hiding the ul element. On the first click, I change the display to none (initially set to visible), but I have to wait until it becomes available again in the DOM before I can hide it once more.

I am currently exploring possible solutions to address this issue. You can find the codepen with the implementation here.

Thank you,

jade

// BEM terminology added, but not yet implemented. Just basic css down there 

nav.desktop
  ul
    li
      a(href="") Home
    li
      a(href="") About
    li
      a(href="") Labs
    li
      a(href="") Contact 

nav.mobile
  .hamburger
    button.hamburger__btn Toggle
    span.hamburger__top
    span.hamburger__middle
    span.hamburger__bottom
  ul.navigation--mobile--hidden
    li
      a(href="") Home
    li
      a(href="#about") About
    li
      a(href="#labs") Labs
    li
      a(href="#contact") Contact
main
  section#about
    h1 About
    p  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Esse dolorum, accusamus officiis possimus cupiditate facere, sequi illum nobis saepe quidem repudiandae magnam natus cum animi repellendus. Illum qui, nobis voluptas.
  section#labs
    h1 Labs
    p  Lorem ipsum dolor sit amet, consectetur ...

// Additional CSS styles follow...

// JavaScript

$(function () {
  var hamburgerBtn =  document.getElementsByClassName('hamburger__btn')[0];
  var navBar = hamburgerBtn.parentNode.parentNode;
  var navBarUlEl = navBar.getElementsByTagName('ul')[0];

  // Makes the hamburger btn clickable
  hamburgerBtn.onclick = function() {
    toggleClass(navBarUlEl);

     var ulNavFlex = document.getElementsByClassName('navigation--mobile--flex')[0];
    var navBarFlex = ulNavFlex.parentNode;

    console.log('This is the ulnavflex: ' + ulNavFlex);
    console.log('This is the navflex: ' + navBarFlex.classList);
    console.log('This is the navbar: ' + navBar.classList);

    var ulNavFlexLinks = ulNavFlex.getElementsByTagName('a');

    console.log(ulNavFlexLinks);
    console.log(ulNavFlex)


    for (var i = 0; i < ulNavFlexLinks.length; i++) {
      toggleLinkClick(ulNavFlexLinks[i]);
    }
}

  // Toggles Link Clicks
  var toggleLinkClick = ...

// The script continues...

Answer №1

It appears that there is a logical error in the code. When a section is selected from the menu, two classes - animate and navigation--mobile--hidden are added in the toggleLinkClick listener. However, when the menu is clicked again, the toggleClass function fails to update the class properly. To resolve this issue, you can modify the toggleClass function as shown below:

 var toggleClass = function(el) {
    if ($(el).hasClass('navigation--mobile--hidden')) {
      el.className = 'navigation--mobile--flex';
    } else if ($(el).hasClass('navigation--mobile-flex')) {
      el.className = 'navigation--mobile--hidden';
    } else {
      el.className = 'navigation--mobile--hidden';
    }
  }

Please note: I have used jQuery to check for the existence of a class since you have utilized jQuery.

Alternatively, another way to address this issue is to remove the animate class once the animation is completed in your toggleLinkClick listener, like so:

 var toggleLinkClick = function(el) {
    el.onclick = function() {
        console.log('I was clicked from: ' + el)
        if (navBarUlEl.classList == 'navigation--mobile--flex') {
          navBarUlEl.classList.add('animate');
          navBarUlEl.classList.remove('navigation--mobile--flex');
          navBarUlEl.classList.add('navigation--mobile--hidden');
          navBarUlEl.classList.remove('animate');
        }
        console.log(navBarUlEl.classList);
      }
  }

In this scenario, you won't need to modify your toggleClass function to include an if statement.

For a demonstration of the second solution, visit this CodePen link. And for the first solution, refer to this CodePen link.

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

Node.js allows for keeping pipe and sockets open even after streaming an HTTP response

My current challenge involves streaming data from an HTTP response to a cloud storage provider within an internal service. const response = await request<Readable>({ headers: httpOpts?.headers, data: httpOpts?.data, url, method, responseTyp ...

Need help speeding up website load times?

My website is loading incredibly slow, even though it has minimal content. I suspect that the high number of images and JavaScript elements on the page are contributing to this issue. Is there a method available to diagnose what exactly is causing the ext ...

manipulating dropdown visibility with javascript

I'm feeling a bit lost on how to structure this code. Here's what I need: I have 5 dropdown boxes, with the first one being constant and the rest hidden initially. Depending on the option chosen in the first dropdown, I want to display the corres ...

What is a creative way to get rid of old content on a webpage using jQuery without relying on the

As I work on my crossword project, I have almost completed it, but encountering a problem. Within my HTML code, I have a select list that loads a .JSON file using Javascript. <form method="post" id="formulaire"> <div class="toto"> <sel ...

Tips on creating a React Vite Typescript website that utilizes the entire height and ensures a minimum width

I'm currently working on building a portfolio webpage with React, Vite, and Typescript, but I'm facing an issue where the content is not taking up the full height of the page. I have multiple pages with different lengths of content that I want to ...

Is there a way to transform JSON text into a JSON object?

Similar Question: How do I convert JSON to a JavaScript object? { "data": [ { "name": "JoongBum Lee", "id": "526210623" }, { "name": "\uc774\uc778\uaddc", ...

Enhancing visual aesthetics with Vuetify on v-slot label components

I am working with Vuetify code that appears like this <v-radio-group v-model="gender" column class="radio-group-full-width"> <v-radio value="Boy"> <template v-slot:label> <v-textarea v-model="answer" v-vali ...

The request cannot be completed using GET. The connection has not been established, and the offline queue is not activated

Encountering this unexpected error in the live environment, despite implementing a retry strategy of 500ms and wrapping the setAsync and getAsync functions with a setTimeout of 1s. It's puzzling why this issue persists. Error Message: AbortError at ...

When the parent element has a fixed position, the child element will no longer maintain its floating property

I'm currently working on a fixed navigation panel that sticks in place while scrolling down. Here is the code I have so far: <header> <a class="logo" href="/">Logo_name</a> <nav> <a href="#">Menu_1</a& ...

Having trouble changing fonts in JavaScript Photoshop using scripting on certain fonts

I have created a script for photoshop that is designed to change the font family to a different type. However, I am experiencing some inconsistencies in its performance. Here is the section of the script responsible for altering the font family: var origD ...

What is the best way to set up a React handler that can handle multiple values effectively?

Struggling with a handler that is not behaving as expected. I need to update the 'quantity' value of multiple items, but currently they all get updated with the last value entered. How can I change multiple values and update items individually? H ...

Utilize Bootstrap tooltips to display live results fetched via an AJAX call

I have a bootstrap tooltip that I am trying to populate with data from an AJAX request. The text retrieved from the request should be displayed as the title property of the tooltip. Despite successfully executing the AJAX request, I am facing two issues: ...

Invoke a function using the output of a different function

There is a function whose name is stored in the value of another function, and I need to invoke this function using the other one. The function I need to call is popup() random() = 'popup()' if ($.cookie('optin-page')) { } I attemp ...

Is there a way to detect a specific button press in react-native-picker-select?

I am currently utilizing the react-native-picker-select library. My objective is to set ingrebool to false when options a, b, c, or d are selected and true when option e is chosen from the data called ingre. How can I achieve this? Here is my code snippet ...

Creating dynamic movement on webpages using CSS3 Animations

Exploring the world of CSS animations is such a blast! I've created this fiddle to play around with the concept of wheels on a bus. Check out my JS Fiddle here One strange thing I noticed is that sometimes there's a white space between the two ...

The issue of basic authentication failing to function on Internet Explorer and Chrome, yet operating successfully on Firefox

Here is how my authentication code looks: public class BasicAuthenticationMessageHandler : DelegatingHandler { private const string BasicAuthResponseHeader = "WWW-Authenticate"; private const string BasicAuthResponseHeaderValue = "Basi ...

What is the best way to encode only a specific section of a JavaScript object into JSON format?

Currently, I am in the process of developing a 2D gravity simulation game and I am faced with the challenge of implementing save/load functionality. The game involves storing all current planets in an array format. Each planet is depicted by a Body object ...

Inverted CSS Shadow Box

I thought I had a good grasp on how CSS shadow-box works, but it seems I was mistaken. Could someone provide me with a visual explanation of why the <hr/> looks the way it does here? Take a look at style 13: https://codepen.io/ibrahimjabbari/pen/ozi ...

Explore the various timer functionalities available in Angular.js

I am working on a project that requires displaying two timers on a webpage, each with different start times. The first timer should only show for 5 seconds, and then after 10 seconds, the second timer should be displayed. I am new to Angular and have writ ...

Pressing a button through xpath

I am attempting to click on the button below: <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"> <div class="ui-dialog-buttonset"> <button class="ui-button ui-widget ui-state-default ...