How can we use JavaScript to close a dropdown menu when the user clicks outside of it?

I am facing an issue with my code. I want to close the dropdown menu when clicking outside of it or on the items within the dropdown. How can I achieve this?

I attempted to use

addEventListener('click', myFunction)
on `document` but it did not work as expected. I also looked for solutions on Stack Overflow, but most of them involved jQuery. Can someone help me fix this issue?

.block {
  display: block !important;
}
<div class="dropdown" style="position: relative;display: inline-block;">
  <button class="dropbtn" onclick="dropdown()" style="padding: 16px;font-size: 16px;border: none;cursor: pointer;">Dropdown</button>
  <div class="dropdown-content" id="dropdown" style="display: none;position: absolute;min-width: 160px;box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);z-index: 1;">
    <a href="#" style="color: black;padding: 12px 16px;text-decoration: none;display: block;">Yes</a>
    <a href="#" style="color: black;padding: 12px 16px;text-decoration: none;display: block;">No</a>
  </div>
</div>
<script type="text/javascript">
  function dropdown() {
    document.getElementById("dropdown").classList.add("block");
  }
</script>

If I use the following code, the dropdown menu doesn't even open:

document.addEventListener("click", myFunction);
function myFunction(){
  document.getElementById("dropdown").classList.remove("block");
}

Thank you for your attention :)

Answer №1

Your approach will result in the closure of the app every time something on the document is clicked, which is not desired.

To prevent this, listen for the onclick event on the document but make sure to exclude the scenario when it is clicked inside your box:

.block {
  display: block !important;
}
<div class="dropdown" style="position: relative;display: inline-block;">
  <button class="dropbtn" onclick="dropdown()" style="padding: 16px;font-size: 16px;border: none;cursor: pointer;">Dropdown</button>
  <div class="dropdown-content" id="dropdown" style="display: none;position: absolute;min-width: 160px;box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);z-index: 1;">
    <a href="#" style="color: black;padding: 12px 16px;text-decoration: none;display: block;">Yes</a>
    <a href="#" style="color: black;padding: 12px 16px;text-decoration: none;display: block;">No</a>
  </div>
</div>
<script type="text/javascript">
  function dropdown() {  document.getElementById("dropdown").classList.add("block");
  }
  
  document.addEventListener("click", myFunction);
function myFunction(){
 if (!document.getElementsByClassName('dropdown')[0].contains(event.target)){ document.getElementById("dropdown").classList.remove("block");
 }
 }
 
</script>

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

Troubleshooting the problem with JavaScript's week start date

I am encountering an issue with JavaScript when trying to obtain the first day of the week. It seems to be functioning correctly for most cases, but there is a discrepancy when it comes to the first day of the month. Could there be something that I am ove ...

Assistance needed with sending JSON data to a PHP server using the POST method

I am attempting to transfer JSON data from an HTML form to a PHP server using the POST method. The issue I am encountering is that my code always ends up in the fail block within the callback function. Despite this, the Firebug console (ctrl+shift+J) does ...

Deactivate the date when it reaches 8 in the current date count using ajax, php, and mysql

I want to prevent users from selecting a specific date after it has been chosen 8 times. Currently, when the date is selected for the 9th time, an alert box pops up. Instead of the alert box, I would like to disable that particular date selection altogethe ...

A method to find the sum of the final n elements in an array by employing Arr.reduceRight

I have successfully calculated the sum of the last n elements in an array using a for loop. Is it possible to achieve the same result using Arr.reduceRight instead? x = [1,2,3,4,5]; y = 0 for(let i=x.length; i>x.length-3; i--) { console.log(x[i-1]); ...

Changing the Value of an Input Element Dynamically in React: A Step-by-Step Guide

In a scenario where I have a component that takes an element, such as <input />, and I need to update its value programmatically after 15 seconds. Initially, I had the following approach in mind: const MyComponent = (myInput: JSX.Element) => { ...

What is the best way to utilize jQuery to expand an HTML form?

For my new web application project, I am working on a feature that allows users to create messages with attached files. Check out this image for multiple HTML file inputs using jQuery: http://img39.imageshack.us/img39/4474/attachments.gif One of the func ...

What is the best way to transfer React context between _document.js and pages in Next.js?

Imagine I have this scenario: export const ThemeContext = createContext(); export function ThemeWrapper({ children }) { const sharedState = { darkMode: false, }; return ( <ThemeContext.Provider value={sharedState}> {children} ...

Having difficulty extracting data from FormData() object and encountering difficulty sending it through the frontend

Whenever I use Postman to send data, the Title, description, and image are successfully transmitted. This is how my post array looks like: router.post('/', uploadS3.array('meme',3),(req, res, next)=>{ // res.json(req.file.locatio ...

The Angular Material date picker unpredictably updates when a date is manually changed and the tab key is pressed

My component involves the use of the Angular material date picker. However, I have encountered a strange issue with it. When I select a date using the calendar control, everything works fine. But if I manually change the date and then press the tab button, ...

Manipulate PHP/SQL Form: Add, Remove, or Modify items

I have utilized the following code for managing a football fixtures and results administration website. The issue I am encountering pertains to the delete syntax (I suspect that there may be an error related to [ID]). Apart from that, everything else seems ...

What is the best approach to concurrently update a single array from multiple functions?

In my React app, I have a form with various input fields and checkboxes. Before making an API call to submit the data, I have functions set up to check if any fields are left blank or unchecked. These check functions are triggered when the form button is ...

What is the reason behind the necessity of using setTimeout with a delay of at least 50ms for JS .focus()

Problem While creating a page for a client at work, I encountered an issue with a slide-out search bar. When clicking the button to open the search input field (which starts off hidden), I want the focus to shift to that input field. Oddly, I found that ...

Renaming and destructuring of an array's length using ReactJS

I am working with a reduce function shown below: let el = scopes.reduce ((tot, {actions}) => tot + actions.length, 0); I attempted to modify it as follows, but it appears that this is not the correct approach: let el = scopes.reduce ((tot, {actions.l ...

Utilize Next.js to send an image to an email by leveraging the renderToString function on the API routes

I need help with sending styled emails that contain images. Currently, I am utilizing the renderToString method to pass props into my component. So far, everything is functioning correctly in the API routes. mport client from "@/lib/prisma"; im ...

Accessing external data in Angular outside of a subscription method for an observable

I am struggling to access data outside of my method using .subscribe This is the Service code that is functioning correctly: getSessionTracker(): Observable<ISessionTracker[]> { return this.http.get(this._url) .map((res: Response) => ...

Creating a drop-down menu in HTML with PHP and MySQL integration

I'm currently working on populating a list into a drop-down menu, but right now it's displaying each name in its own separate drop-down. I'd like to have all the names listed in just one single drop-down instead. Any ideas on how I could ach ...

Setting dynamic routes in Next.js when the basePath is not the root can be done by carefully configuring the routing system

After following a tutorial on setting up my Next.js project to be located in a subfolder (/app), everything was running smoothly. However, I encountered issues when trying to use dynamic routes for certain pages. I attempted three different approaches: ...

Vertical and floating alignment

Can you help me with this HTML/CSS challenge? User: Support: Emily Johnson Alex Roberts I am looking to have two input boxes aligned vertically on both the left and right ...

Repeatedly utilizing a drop-down menu

Can a <select> menu be written and utilized in multiple locations on a webpage? For instance: <select id="dm"> <option value="">Select Quantity</option> <option value="less ">50 - 60</option> <option value="me ...

Understanding the error handling in Express.js

Learning about error handling in express is new to me and I have a straightforward piece of code like this - const express = require('express'); const MongoClient = require('mongodb').MongoClient; const app = express(); let url = &a ...