Only apply prevent default on specific levels for better control

I am currently working on a menu with submenus. I am facing an issue where when I click on a top-level menu item, I need to use prevent default because they are anchor tags. However, for the submenu items, I do not want to prevent default behavior. I am struggling to find a solution that allows me to differentiate between the two levels of the menu.

<div id="block-menu-block-2">
  <ul class="menu">
    <li>
      <a href="#">1</a>
    </li>
    <li>
      <a href="#">2</a>
      <ul class="menu">
        <li><a href="#">2.1</a></li>
        <li><a href="#">2.2</a></li>
        <li><a href="#">2.3</a></li>
        <li><a href="#">2.4</a></li>
      </ul>
    </li>
    <li>
      <a href="#">3</a>
      <ul class="menu">
        <li><a href="#">3.1</a></li>
        <li><a href="#">3.2</a></li>
        <li><a href="#">3.3</a></li>
        <li><a href="#">3.4</a></li>
      </ul>
    </li>
    <li>
      <a href="#">4</a>
    </li>
    <li>
      <a href="#">5</a>
    </li>
    <li>
      <a href="#">6</a>
      <ul class="menu">
        <li><a href="#">6.1</a></li>
      </ul>
    </li>
  </ul>  
</div>

Below is the jQuery code:

$('#block-menu-block-2 ul li').on("click", function() {
if ($(this).children().is('ul')) {
    if ($(this).find('ul').is(':visible')) {
        $(this).find('ul').hide("blind");
        $(this).removeClass('menuItemSelected');
        $(this).find('ul').removeClass('menuItemSelected');
    } else {
        $(this).parent().find('li ul').hide("blind");
        $(this).parent().find('.menuItemSelected').removeClass('menuItemSelected');
        $(this).find('ul').show("blind");
        $(this).addClass('menuItemSelected');
        $(this).find('ul').addClass('menuItemSelected');
    };
    event.preventDefault()
    }
});

For a live example, check out this CodePen link.

Answer №1

Some changes have been made and new content has been added. Unfortunately, I wasn't able to copy it into Codepen from my phone so there may be some issues. The code is presented first, followed by a brief explanation.

$('#block-menu-block-2 ul li').each (function () { 
    var $this = $(this);
    if ($this.find ('ul:first').length > 0) {
        $this.click (function () {
            if ($this.find ('ul:visible').length > 0) {
                $this.removeClass ('menuItemSelected').find ('ul').removeClass('menuItemSelected').hide ('blind');
            } else {
                $this.parent ().find ('ul li').hide ('blind');
                $this.parent ().find('.menuItemSelected').removeClass  ('menuItemSelected');
                $this.addClass ('menuItemSelected').find ('ul').show ('blind').addClass ('menuItemSelected');
            }
        }); 
    }
});
 $('#block-menu-block-2 > ul > li > a').click (function (e) {
    if ($(this).find ('ul:first').length > 0)
        e.preventDefault ();
});

The key point is to apply preventDefault only on the anchor tag when it is directly nested within an li element that is directly inside a ul element which is directly within the block-menu. This can be seen in the last three lines of the code snippet.

The remaining code segment should specifically target li elements containing ul tags for click events. Attempted to optimize by using chaining to reduce jQuery object creation, but might have introduced errors in the process. By removing preventDefault at its original position and following the guidance of the final lines, the desired functionality should be achieved.

Answer №2

Is it possible for you to avoid adding a category to your dropdown menu triggers, like .dropdown-trigger, and then implement the subsequent jQuery:

$(document).on('click', function(e) {
  if ($(e.target).hasClass('dropdown-trigger')) e.preventDefault();
});

Answer №3

To simplify the menu manipulation process, you can focus on attaching the event to <a> elements and then checking if there is a sibling <ul>. If there is, you can prevent the default action.

$('.menu-item-link').click(function(e){
    if( $(this).siblings('ul').length ){
         e.preventDefault();
    }
    // additional menu code 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

NPM: Handling multiple prehooks with the same name

Is it possible to have multiple prehooks with the same name in my package.json file? For example, having two instances of pretest: "scripts": { "start": "react-scripts start", ... "pretest": "eslin ...

Django is refusing to display my CSS and JavaScript files - static files

Within my code in settings.py, I define the static URL like so: STATIC_ROOT = os.path.join(BASE_DIR, "static") STATIC_URL = '/static/' The location of my static files and folders is at /home/myLinuxUsername/myApp/static/interactive-preview-depe ...

Seeking a material design template for mandatory form patterns

I'm struggling with getting my required field patterns to work using regular expressions. Additionally, I'd like to center my 'onboard' button on the page. You can find my code at this StackBlitz link: https://stackblitz.com/edit/angula ...

All hyperlinks are displayed as a single entity

I have 5 image links displayed side by side, but when I hover over them, they act as one collective link. Can someone please assist me with resolving this issue? After updating my code to include the entire div, it seems that there is something within the ...

Is there a way to drop a pin on the Google Maps app?

Is there a way to pinpoint the specific location on Google Maps? <google-map id="map-container" width="100%" height="100%" class="maps"></google-map> ...

What is the best way to connect click events with ExtJS template elements?

Is there a way to assign a click event to each link tag without directly embedding onclick=.... in the XTemplate code? new Ext.XTemplate( '<ul>', '<tpl for="."><li><a href="#{anchor}">{text}</a></li& ...

How can I optimize my Javascript applications for better search engine rankings?

Recently, I've been exploring the idea of implementing a fresh workflow process for web development. Yemoan, Grunt, and Bower in conjunction with AngularJS look promising as a solution for front-end development. However, one major drawback is their po ...

Eliminate the prefixes of object keys in Node.js

This is my first time reaching out for help on a forum. I've been struggling with an issue for days and haven't been able to find a solution. It all started with a database query that returned the following data: { "prod_format": "400 ml", "pro ...

Hide table cells using jQuery if they do not contain a specific content

Is there a way to conceal the td elements in a table that do not have the inline CSS attribute width:12%;? See code example below. <td class="" id=""> <td class="" id=""> <td class="" id=""> <td width="12%" class="" id=""><!-- ...

Positioning divs next to each other in CSS and setting the width of the second

I am attempting to position two divs next to each other. The initial one is 200x200 pixels and the second one should be positioned 10 pixels to the right of the first one. The second div has a height of 200 pixels, and its width needs to extend all the way ...

Empty jQuery $.ajax value after post

I'm encountering an issue where my code's post value appears to be empty. I have attempted to echo the key and value using a foreach loop, but it only shows "0 Array." This is what my code looks like: <script type="text/javascript"> $(doc ...

Dynamic popup in RShiny interface with the ability to be moved around

I am currently working on a dashboard project and I am looking to implement a dynamic popup feature that can be moved around. I have been able to create a pop-up, but it remains static. I would like the flexibility for users to drag and position the popup ...

Maintain HTML formatting when page is refreshed

I am new to HTML and JavaScript, and I'm trying to modify the JavaScript code below so that when I reload the page, it retains the most recent active tab instead of defaulting back to the first tab. Currently, if I click on the second tab for "Paris" ...

How do I set up middleware with async/await in NestJS?

I am currently integrating bull-arena into my NestJS application. export class AppModule { configure(consumer: MiddlewareConsumer) { const queues = this.createArenaQueues(); const arena = Arena({ queues }, { disableListen: true }); consumer. ...

Leveraging Webworkers in an Angular application for efficient data caching with service workers in the Angular-CLI

I am looking to run a function in the background using a worker, with data coming from an HTTP request. Currently, I have a mock calculation (e.data[0] * e.data[1] * xhrData.arr[3]) in place, but I plan to replace it with a function that returns the actual ...

How can I toggle the visibility of a div based on whether a variable is defined or not?

How can I display a specific div on my webpage only when certain variables in PHP pull out a specific result from a database? I attempted to use the code snippet below, but it's not working as expected. Can someone provide guidance on how to achieve ...

Adding elements to a JSON array in JavaScript/AngularJS

Looking for help with inserting a new item "uid" into a JSON array. Here is the initial array: var testArr=[{name:"name1",age:20},{name:"name1",age:20},{name:"name1",age:20}] The desired output after inserting the "uid" would be: var testArr=[{name:"nam ...

Vuejs components that have checkboxes already selected out of the box

Hey there, I'm facing a small issue. Whenever I click on the areas highlighted in the image, the checkbox on the left gets marked as well. Any idea why this might be happening? https://i.stack.imgur.com/nqFip.png <div class="form-check my-5&qu ...

I am having trouble getting text to display properly in a jQuery Mobile dialog

I am attempting to dynamically set the header and button texts using JavaScript, but unfortunately it's not working as expected. To demonstrate the issue, I have added my code on jsfiddle: http://jsfiddle.net/tMKD3/8/. Here is the HTML code: <bod ...

Activating gzip compression using fetch.js

I am utilizing fetch.js (https://github.com/github/fetch) to transmit a rather substantial JSON object to the backend. The size of the JSON is significant due to it containing an SVG image string. My question is whether fetch.js applies gzip compression a ...