The preventDefault() function is not functioning properly on the <a> tag

As a JavaScript beginner, I decided to create an accordion menu using JavaScript. Although I was successful in implementing it, I encountered a bug in my program.

In this scenario, uppercase letters represent first-level menus while lowercase letters represent second-level menus.

The condition I wish to apply is as follows:

If A has children, clicking on A should display "a b c d".

If A does not have children, then the click on A should simply navigate to the linked page.

I am currently facing a roadblock where the implementation works slightly differently than intended:

If A has children, when clicked on A, it shows "a b c d". If A does not have children, A is not clickable.

Below you can find the source code:

MyJSFile.js


$(document).ready(function(){
  $("#nav > li > a").on("click", function(e){
    if($(this).parent().has("ul")) {
      e.preventDefault();
    }

    if(!$(this).hasClass("open")) {
      // hide any open menus and remove all other classes
      $("#nav li ul").slideUp(350);
      $("#nav li a").removeClass("open");

      // open our new menu and add the open class
      $(this).next("ul").slideDown(350);
      $(this).addClass("open");
    }

    else if($(this).hasClass("open")) {
      $(this).removeClass("open");
      $(this).next("ul").slideUp(350);
    }
  });
});

Here is my CSS class MyCSS.css


#nav {   
  padding-left:0px;
  display: block; 
  width: 100%;
  margin: 0 auto;
}

#nav li {
    list-style-type: none;
}
#nav > li > a:hover, #nav > li > a.open {
    color: #FFF;
    background-color: #38454B;

    background-image: -webkit-gradient(
    linear,
    left top,
    left bottom,
    color-stop(0.35, #212121),
    color-stop(1, #866F4A));
    background-image: -o-linear-gradient(bottom, #212121 35%, #866F4A 100%);
    background-image: -moz-linear-gradient(bottom, #212121 35%, #866F4A 100%);
    background-image: -webkit-linear-gradient(bottom, #212121 35%, #866F4A 100%);
    background-image: -ms-linear-gradient(bottom, #212121 35%, #866F4A 100%);
    background-image: linear-gradient(to bottom, #212121 35%, #866F4A 100%);
}

#nav li ul {
    display: none;
    background-color: #CCC;
    list-style-type: none; 
}

Here is the HTML nav


 <nav>
      <ul id="nav">
        <li><a href="">Home</a></li>

        <li><a href="Go to page 1">Podiatry</a>
          <ul>
            <li><a href="Go to page 2.1">Overview</a></li>
            <li><a href="">*Podiatric Diabetes</a></li>
            <li><a href="">*Pediatric Podiatry</a></li>
            <li><a href="">*Sports Podiatry</a></li>
            <li><a href="Go to page 2.3">Tips from the podiatrist</a></li>
          </ul>
        </li>

        <li><a href="index.php?country=US&page=contact">Contacts</a>
          <ul>
            <li><a href="http:/www.google.com/search?q=web+design+icons">Link 1</a></li>
            <li><a href="http:/www.google.com/search?q=web+design+tutorials">Link 2</a></li>
            <li><a href="http:/www.google.com/search?q=web+design+user+interface">Link 3</a></li>
            <li><a href="http:/www.google.com/search?q=web+design">Link 4</a></li>
          </ul>
        </li>
      </ul>
    </nav>

Third party edit:

Check out the JSFiddle link for the code: http://jsfiddle.net/3STdc/

Answer №1

When using <code>$(this).parent().has("ul")
, it will always evaluate to true because it returns a jQuery object.

Consider using

if ($(this).parent().has("ul").length)

Check out this JSFiddle link for reference.

You can also opt for the shorter version:

if ($(this).siblings('ul').length)
, which works just as well.

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

Tips for condensing text using ellipsis and Angular-FlexLayout

I am working on a flex row setup that includes three nested flex rows. Within the second row, I need to display a title that should not be shortened, and a text that should be truncated. Additionally, the first and last row must maintain a fixed width with ...

Unable to get jQuery accordion to function as expected when using content retrieved through AJAX requests

Seeking assistance with a malfunctioning accordion that is not working after receiving content from another page through AJAX. The problematic page in question can be found at: Upon loading the page, it sends a default city name to processtempo.php which ...

How to Insert a Background Image into Advanced Custom Fields (ACF) using CSS

Hey there, I'm facing a bit of a challenge with this particular section. In the past, I've only included ACF PHP within HTML when the background image was directly in the HTML code. Now, however, I have two shapes specified in my CSS using pseudo ...

A guide on expanding an HTML table dynamically with MVC razor syntax

My goal is to dynamically add new rows to a table by following the advice given in this answer on Stack Overflow: Add table row in jQuery I have successfully implemented it for one of my table requirements as seen below: function onAddItem() { $( ...

Facing problem with implementing NgMoudleFactoryLoader for lazy loading in Angular 8

A situation arose where I needed to lazy load a popups module outside of the regular router lazy-loading. In order to achieve this, I made the following adjustments: angular.json "architect": { "build": { ... "options": { ... "lazyM ...

A tutorial on adjusting camera angles through mouse dragging in Three.js

I have created a unique Rolex cube with varying layers along the "Z axis" and I need to adjust the camera position to preview the geometry accurately. How can I change the camera position by dragging the window and also manipulate individual cone rotations ...

What is the method for modifying the chosen color using a select option tag instead of a list?

element, I have a Vue component that features images which change color upon clicking a list item associated with that color. <div class="product__machine-info__colors"> <ul> <li v-for="(color, index) in machine.content[0] ...

Setting up initial values for React properties

Below is the React code snippet I am currently working with: this.state = { colsHiddenStatus: new Map([['rowNumber',true], ['id', false], ['firstName', false], ['lastName', false], ['mobile', false], [&a ...

Placing two images within one div tag

I've been attempting to place two images within a single div, but they're not appearing how I intended. I'd like there to be some space between the images, but that's not happening. Here's the CSS I'm using: .sidebarBody { ...

What is the best way to adjust the height and width of a div when it comes into view through scrolling?

How can I automatically and frequently change the size of my div when it is scrolled into view? HTML <div id="contact" class="fadeInBlock"> <div class="map"> <div class="pointer"> <div class="dot"></div& ...

Display a video-thumbnail in place of a static image when sharing a link

When setting up my website, I made sure to include OpenGraph metadata to customize how it appears when shared on social networks and messaging apps. This includes specifying the thumbnail, title, and description: <meta property="og:title" content="Titl ...

The error message "TypeError: Trying to access properties of an undefined object (reading '800')" is being displayed

Every time I launch my application, I encounter the error message: "TypeError: Cannot read properties of undefined (reading '800')". import React, { useState } from 'react'; import { Menu, MenuItem, Avatar, Box, ThemeProvider} ...

Achieve a full height for children without the need to specify a fixed height for the

I'm currently working on a container div that houses two child divs: the first one, positioned to align with its parent's left border, contains a series of buttons while the second one holds the main content. In essence, it operates like a tab na ...

In Vue.js, you can utilize one property to access additional properties within the same element

Is it possible to access other properties of the same element using a different property in Vue.js? For example: Rather than writing it like this: <kpi title="some_kpi" v-if="displayed_kpi==='some_kpi'"></kpi> I ...

Convert Ajax null value to NoneType in web2py

Every time I save information on a page, an AJAX request is sent with all the necessary data to be stored in the database. The format of this data looks similar to this example: {type: "cover", title: "test", description: null, tags: null} However, when ...

Revitalizing and rerouting page upon button click

The issue at hand is: When the "Post now" button is clicked, the modal with the filled form still appears. If the button is clicked again, it adds the same data repeatedly. I aim to have the page refresh and navigate to a link containing the prediction d ...

Teaching etiquette to the students of Li

I'm having trouble getting two lists to display correctly on my website. I want one main navigation list that is horizontal and another sub navigation list that is vertical. To achieve this, I need to have two different classes for the list items in m ...

The close button for Fancybox gets cropped out when Foundation 3 and CSS border-box are used together

When the box-sizing is set to border-box, it can sometimes cut off the "close" button. This issue seems to be more prevalent when using Foundation 3 by Zurb. The snippet of code that may be causing conflicts with fancybox is as follows: * { box-sizin ...

Challenges with login pages integrating JS/JQuery and Firebase

I've been working on creating a login page where once the user successfully logs in, I want to make it so that they are redirected from the index.html page to my portfolio.html page. firebase.auth().onAuthStateChanged(user => { if(user) { wind ...

Storing blank information into a Mongodb database with Node.js and HTML

Can someone please assist me with solving this problem? const express=require("express"); const app=express(); const bodyparser=require("body-parser"); const cors=require("cors"); const mongoose=require("mongoose"); ...