Guide on hiding a div element when clicked outside of it?

How can I create a dropdown feature in Khan Academy where it disappears when clicked outside but stays visible when clicked inside, using JavaScript/CSS/HTML? The current implementation closes the dropdown even on internal clicks. The code includes an event listener attached to the document's click event to hide the dropdown if the clicked element is not the dropdown itself or the account image. What is causing this issue and how can it be fixed to achieve the desired functionality within Khan Academy's limitations? Here is the attempted code:

// Function to open the account dropdown
function openAccdrpdwn() {
  document.getElementById("acc-drpdwn").style.display = "block";
}

// Event listener to open the account dropdown when clicking on the account image
document.getElementById('account-signin').addEventListener('click', openAccdrpdwn);

// Event listener to close the account dropdown when clicking outside of it
document.onclick = function(event) {
  var dropdown = document.getElementById("acc-drpdwn");
  var accountImage = document.getElementById("account-signin");

  if (event.target !== dropdown && event.target !== accountImage) {
    dropdown.style.display = "none";
  }
};
#account {
  background-color: rgb(247, 247, 247);
  width: 175px;
  height: 300px;
  border-radius: 17px;
  position: absolute;
  top: 68px;
  left: 408px;
  box-shadow: 0px 0px 7px 3px lightgray;
  z-index: 1;
}
...

The above code doesn't work correctly as the dropdown still disappears when clicked inside. Any suggestions on how to implement this feature properly within Khan Academy's environment?

Answer ā„–1

Take a look at the example provided below

<!doctype html>
<html lang="en" onclick="bubbleOut(this)">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <script>
    function bubbleOut(self) {
      const domRef = document.getElementById("disappear");
      domRef.remove();
    }
    function eatTheclick(ref) {
      event.stopPropagation();
    }
  </script>
  <body style="border: 1px salmon solid">
    <div
      style="width: 100px; height: 500; border: 1px solid red"
      onclick="eatTheclick(this)"
    >
      <p id="disappear">Click me to keep me. Click outside of the red block and I stay</p>
      <div>I will remain</div>
      <div>And so will I</div>
    </div>
  </body>
</html>

You can save this code as an HTML file and then view it in a browser. While not an exact solution to your issue, you could adapt a similar approach in your own code.

  1. The root HTML element has an onclick event that references the element to be removed when clicked.

  2. The element itself contains an onclick event that prevents click propagation.

Answer ā„–2

Since the dropdown contains child elements, the target of the event may not necessarily be the dropdown itself but one of its children. To handle this situation, you can check if the event.target is a descendant of the dropdown:

if (!dropdown.contains(event.target) && event.target !== accountImage) {
  dropdown.style.display = "none";
}

// Function for displaying the account dropdown
function openAccountDropdown(event) {
  event.stopPropagation(); // Prevent document.onclick from triggering when opening the dropdown
  document.getElementById("acc-drpdwn").style.display = "block";
} // Event listener to display the account dropdown upon clicking on the account image
document.getElementById('account-signin').addEventListener('click', openAccountDropdown);
// Function for displaying the account dropdown

// Event listener to hide the account dropdown when clicked outside of it
document.onclick = function(event) {
  var dropdown = document.getElementById("acc-drpdwn");
  var accountImage = document.getElementById("account-signin");

  if (!dropdown.contains(event.target) && event.target !== accountImage) {
    dropdown.style.display = "none";
  }
};
#account {
  background-color: rgb(247, 247, 247);
  width: 175px;
  height: 300px;
  border-radius: 17px;
  position: absolute;
  top: 68px;
  left: 408px;
  box-shadow: 0px 0px 7px 3px lightgray;
  z-index: 1;
}

#inside-account {
  background-color: rgb(209, 255, 215);
  width: 175px;
  height: 80px;
  border-top-right-radius: 17px;
  border-top-left-radius: 17px;
  position: absolute;
  top: 68px;
  left: 408px;
  z-index: 2;
}

#acc-drpdwn {
  display: none;
}

.account-image {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  position: absolute;
  left: 0px;
  top: 1.8px;
  cursor: pointer;
}

#account-image {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: #ccc;
  position: absolute;
  left: -2px;
  top: -2.2px;
  float: left;
}
<button class="account-image" id="account-signin">
  <img id="account-image" src="https://upload.wikimedia.org/wikipedia/commons/9/99/Sample_User_Icon.png" alt="Sample User Icon">
</button>
<div id="acc-drpdwn">
  <div id="account">Account</div>
  <div id="inside-account">Inside Account</div>
</div>

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

Link embedded within a list item

How can I make the hyperlink element fill up the width and height of the li element inside? <ul> <li><a href="#" style="display: block; width: 100%; height: 100%;">this link to fill up the li element width and height</a><l ...

What is the best way to showcase the outcome using the <table> tag in HTML with columns containing 50 records each, except for the final column?

I have developed a program that is currently creating 540 different numbers. My goal is to present these 540 distinct numbers in columns with 50 records each (except for the last column where there may be fewer than 50 records) using the HTML <table> ...

Issue with Safari div not exhibiting proper overflow functionality

I'm looking to set up a webpage with a single sidebar and content area. Here's how I envision it: <div id="mainWrapper"> <!-- Sidebar --> <div id="sidebar"> <p>Sidebar</p> <p>Sidebar< ...

Instructions for running a script from a personalized NPM package

I have developed a unique NPM package that includes a script I want to run from another project. Here is an overview of my package: myScript.js console.log("The script has been executed!"); package.json { "name": "@myscope/my-script", "version": "0. ...

Can you show me a way to use jQuery to delete several href links using their IDs at once?

Currently facing a challenge with removing multiple href links that share the same ID. Here is a snippet of my code: $('.delblk').click(function(e) { e.preventDefault(); var id = $(this).attr('id').substr(7); ...

An efficient method for removing a column using JavaScript

Hello, I'm seeking assistance with the following code snippet: $(document).on('click', 'button[id=delete_column]', function () { if (col_number > 1) { $('#column' + col_number).remove(); $('#col ...

Angular custom filter applied only when a button is clicked

I have recently started exploring angular custom filters and I am curious to know if there is a way to trigger the filters in an ng-repeat only upon clicking a button. Check out this example on jsfiddle : http://jsfiddle.net/toddmotto/53Xuk/ <div ...

Is it possible to obtain the X-Y coordinates of the ray collision location in relation to the targeted face?

I have been working on determining the ray collision coordinate in relation to the targeted face... The following is my code snippet: var fMouseX = (iX / oCanvas.width) * 2 - 1; var fMouseY = -(iY / oCanvas.height) * 2 + 1; //Utilizing OrthographicCamer ...

Adding and Removing Attributes from Elements in AngularJS: A Step-by-Step Guide

<input name="name" type="text" ng-model="numbers" mandatory> Is there a way to dynamically remove and add the "mandatory" class in Angular JS? Please note that "mandatory" is a custom class that I have implemented. Thank you. ...

Changing the direction to reverse column will cause the navigation component to be hidden

Issue: The <Navigation/> components disappear when using flex-direction: column-reverse. However, if I switch to flex-direction: column, the component appears at the top of the screen and is visible. My objective is to display my <Navigation/> ...

Guide on displaying the marker location on a map when hovering over a div element, similar to the method used by AirBnb

In the left side div of my page, there are items such as images, titles, details, and addresses. On the right side, I have a Leaflet Map that shows markers of these addresses taken from the left side items. What I want is to display the marker locations on ...

If element Div is labeled as either A, B, or C, it should smoothly fade out and then fade in as Div

I'm currently working on enhancing the navigation of my portfolio website and Iā€™m facing a challenge in adding additional properties to my toggle() function. This basically involves creating a filter system with four possible options, which are: ...

Using Ajax to preview images results in displaying a broken image icon

I am currently working on implementing an image preview function using Ajax. As I was experimenting, a couple of questions came to my mind: Once the Ajax has been executed, is the actual image uploaded to the server or just an array containing strings l ...

Splitting a td tag into multiple columns dynamically with Angular

I am attempting to dynamically split the table element into separate columns. My desired layout should resemble this: The values for name and surname are fixed at 1, but the values for subjects and grades can vary (there may be 2 or more columns). Below ...

Text Separation Within a Singular JSON Object

Currently, I am offering my assistance as a volunteer to develop a fast AngularJS App for a non-profit organization. Although I have successfully set up Angular, the main issue I am encountering has to do with parsing JSON data. The JSON object that I am ...

What could be causing the CSS height percentage to malfunction?

I'm having trouble with some basic CSS that uses percentages. I've labeled everything and checked my code, but it still isn't working properly. Here's the CSS code snippet: .BoxHeight { height: 100%; } #Box { margin-top: 0%; mar ...

No cookie found in the system

Attempting to create an effect using bloom and shaders in post-processing. However, encountering an error in the console with a blank white screen. I have tried clearing cookies, caches, and even running this in incognito mode, but it's still not work ...

CSRF validation did not pass. The request has been cancelled. The failure occurred due to either a missing or incorrect CSRF token

Upon hitting the submit button in the login form, I encountered the following error message: Forbidden (403) CSRF verification failed. Request aborted. CSRF token missing or incorrect. settings.py MIDDLEWARE = [ 'django.middleware.security.Secur ...

{ 'Name:UniqueRewrite': { token: 738561, number: 2021.8 } }

Is there a way to extract the token value from this data in Node.js? console.log({'Name:Test': { token: 738561, number: 2021.8 } }) I need to isolate just the token and store it in another variable. ...

Is it possible to align the link to the right side of the footer?

I am puzzled as to why the Back to top link does not float to the right of the "footer area" which has a width of 960px. Upon running my code, the back to top link ends up in the middle of the footer. Here is the snippet of my code - can anyone identify th ...