How can I use jQuery to automatically close a Dropdown menu when clicking anywhere else on the page?

I have implemented a dropdown menu that appears when inline text links are clicked. The jQuery click event is used to show the dropdown menu upon clicking a link.

My goal is to make the dropdown menu revert to a hidden state when a click is made anywhere on the page. Currently, you have to click the link again to close the menu.

Check out the demo here

Here is the jQuery code:

// Show Dropdown Menu when link is clicked
$(function(){
  $(".inline-dropdown-menu").click(function(e){
    $(this).find(".inline-dropdown-menu-list:first").toggle();
    e.preventDefault(); // Stop navigation
  });
});

And here is the HTML markup:

<span class="inline-dropdown-menu">
    <a href="">My Link that reveals a DropDown Menu when clicked on<span class="caret"></span></a>

    <ul class="inline-dropdown-menu-list">
        <li class="bottomBorder">
            <a href="" tabindex="-1">alphabetically</a>
        </li>
        <li>
            <a href="" tabindex="-1">2. the first report, alphabetically</a>
        </li>
        <li>
            <a href="" tabindex="-1">3. the first report, alphabetically</a>
        </li>
    </ul>
</span>

Answer №1

http://codepen.io/anon/pen/HgMxE

$(function () {
    $(".inline-dropdown-menu").click(function (e) {
        $(".inline-dropdown-menu-list").hide(); // hides other dropdowns
        $(this).find(".inline-dropdown-menu-list:first").toggle();

        e.preventDefault(); // Prevent default action
    });
});

// Hide dropdown if you click outside of inline-dropdown-menu class

$(document).click(function (e) {
    var container = $(".inline-dropdown-menu");
    if (!container.is(e.target) && container.has(e.target).length === 0) {
        $(".inline-dropdown-menu-list").hide();
    }
});

Answer №2

Check out this helpful code snippet:

let isOpen = false;

$(".inline-dropdown-menu").click(function(event){
    $(".inline-dropdown-menu-list").not(':hidden').hide();
    $(this).find(".inline-dropdown-menu-list:first").toggle();
    event.preventDefault(); // Prevent default action
    isOpen = true;   
});

$('body').click(function(){
    if (isOpen) {
        isOpen = false;
        return;
    }

    $(".inline-dropdown-menu-list").not(':hidden').hide();
});

Answer №3

give this a shot

$(document).ready(function(){
  $(".custom-dropdown").click(function(event){
    event.stopPropagation();
    $(this).find(".dropdown-menu:first").toggle();
    event.preventDefault(); // Prevent default action
 });

$("body").click(function(event){
$(".dropdown-menu").hide();
});

});

Answer №4

When a user clicks on the link, an event is added to the body. Once the body is clicked, the dropdown menu will be hidden and the event on the body will be removed. A setTimeout function is used to prevent double-clicking. Additionally, a namespace "click.ddls" is added to the body click event to allow for other click events.

Take a look at this demonstration: http://example.com/demo

// Display Dropdown Menu on link click
$(function(){

  $(".inline-dropdown-menu a").click(function(e){
      e.preventDefault(); // Prevent navigation
      $("body").off("click.ddls");
      $(".inline-dropdown-menu-list").toggle();

      // Prevent double-click
      setTimeout(function(){
          $("body").on("click.ddls", function(){
              console.log("Body was clicked");
              $(".inline-dropdown-menu-list").hide();
              $("body").off("click.ddls");
          });
      }, 300);
  });

});

Answer №5

If you don't use unique class names, you can iterate through them to determine if they are visible and then close them. Although the following code may not be functioning properly (apologies for that), it can guide you in the right direction. Personally, I prefer using on("click") over click() especially when dealing with dynamic elements that are not yet accessible to the DOM.

     $('*').not(".inline-dropdown-menu").on("click", function(){
         $('.inline-dropdown-menu-list').each(function() {
             if ($(this).is(":visible")) {
                 $(this).toggle();
             }                                                                 
         });

You could also create a counter based on

$('.inline-dropdown-menu-list').length
and assign a data-id to each one so you can match and keep track of them. I hope this explanation is helpful to you.

Answer №6

Let me clarify, you're looking to mimic the functionality of a drop-down arrow when clicking on the body. If that's the case, give this a try:

$("body").click(function(e){
$('.inline-dropdown-menu.open ').find('.inline-dropdown-menu-list:first').toggle();
});

Check out the demo here. Keep in mind that clicking on the body again will toggle the drop-down once more. Feel free to customize this behavior to your liking.

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

The Nestjs cronjob is having trouble accessing the injected service

After setting up a cronjob to call a service from another module, I encountered an issue where the console logged items were displaying correctly when running the method manually from the endpoint. However, once I added back the cronjob decorator, the serv ...

CDK deployment of lambda functions does not currently support the importing of Typescript modules

I’m currently using CDK to develop my serverless application in AWS. However, I encountered an issue where the lambda function fails to import TypeScript modules as JavaScript modules post TS file compilation. As a result, I am encountering a “Module ...

Removing an item with Ajax upon page reload

After creating a small Ajax script to remove items from my database and view, I encountered an issue where the view was only updated after a reload when the item was removed. I want to avoid reloading the entire page by using window.location.reload() in m ...

Tips on how to highlight a clicked list item:

I'm currently attempting to access the key={1} Element within my li. My goal is to set the activeItem in State in order to compare it with the clicked item later on. If they are equivalent, I want to apply an active class to that specific element. How ...

Execute the PHP file using a script tag

Is there a way to include PHP code within <script>? For example, like this: `<script src="example.php">. I understand that the script tag is typically used for JavaScript, but I want PHP to generate JS that can be inserted using the s ...

I require access to the Google Places API in order to implement search functionality for

I need help with creating a form for users to enter their origin and destination zip codes. I managed to get one input field working, but the other is giving me some trouble as I'm still learning. I attempted to use getElementsByClassName <form ...

Apply a 100% width to an image within an animation

Trying to make an image swapper using only CSS has been a smooth process so far with the animation feature effortlessly handling the image swaps. However, the challenge arises when the images themselves are not the perfect size and I'm using a div wit ...

Using the Mousetrap binding on a nuxt.js page may not be effective

Hey there! I'm trying to achieve a certain functionality where I want to redirect to a different page once a specific sequence is typed. Although I can see the message "It works" in my console, the redirection is not happening and instead, I am gettin ...

What's the best way to stack two input fields vertically and combine them into a single unit?

My goal is to have two inputs placed inside a container, one above the other with no space in between and without separate borders for each input. I am using Bootstrap, but so far my attempts with vertical alignment have been unsuccessful. Here is the code ...

Unable to position a div alongside a fluid div with minimum and maximum widths

Within this container, there is a div. #leftBanner { height: 100%; background-color: #CCC; width: 22%; min-width: 245px; max-width: 355px; float: left; } This particular div doesn't cooperate when I try to float another div next to it. While I could ...

Guide on redirecting a web page using jQuery

My function is to display a specific section on the same page when a value is selected from a dropdown list. All content IDs will be on the same page, so I need to navigate to that section based on the selected value. Dropdown list options: <sel ...

Multiple charts experiencing disappearing x-axis labels on Flot

When trying to display two separate bar graphs, the x-axis labels seem to disappear. However, when only one graph is displayed, the labels show up perfectly fine. Any thoughts on why this might be happening? Here is the code snippet for displaying two gr ...

Create a unique custom spinning loader for a straightforward Vue.js application

I've set up a basic Vue project on codesandbox.io that includes vue-router and a custom spinner for loading. Spinner.vue: <template> <div class="spinner" v-show="loading"> <span class="sync" v-bind:style="[spinnerStyle, spinnerD ...

Organize your information starting from the left and moving to the right

Currently, I am engaged in a project where I need to retrieve commands and showcase them on a screen. However, there seems to be an issue as the commands are appearing one by one and automatically moving down to the footer. What I actually want is for th ...

Tips for aligning text to the right within a div using the "justify" text-align property

I want the final sentence of my content to be aligned to the right side while the rest remains justified. I attempted using a <span> within a <p> tag, but it did not work as expected: span.activity-conclusion { font:22px 'Open Sans ...

Error: The $http variable in Vue Resource is not defined

I encountered an issue with the following code snippet inside my ready method: this.$http.get('url',{},{ headers: { "X-App-Token": "token" } }).then( (data) => this.$set('cdata',data.data)) ...

Achieving parent element offset in JavaScript using AngularJS

console.dir(element[0].parentElement) console.dir(element[0].parentElement.offsetTop) In AngularJS, I am attempting to retrieve the offset of a parent element. I am looking to gather details about the parentElement. The first row shows that parentElemen ...

The Empty Spaces Surrounding the Navigation Bar in HTML/CSS

I am just starting out with CSS and HTML. Is there a way to eliminate the gaps around my navigation bar? Here is an example image showing the gaps around the navbar. I have attempted using width and height attributes but it did not resolve the issue. ...

Avoid re-running the onScroll function until completion

I have a unique idea for a slideshow where the slides fade in and out as the user scrolls up or down. The process involves detecting scroll movements and showing the next slide based on the direction of the scroll. The user scrolls using the scrollwheel ...

Issues with jQuery change function in Internet Explorer

if (jQuery(select).hasClass('super-attribute-select')) { jQuery(select).on('change', function() { alert('select babe'); }); } For some reason, the onChange event doesn't seem to be triggering in Internet Explo ...