[javascript] How can I close a dropdown on click outside?

NOTE: For those wanting to use web workers and you need to avoid using document and nativeElement this will work.

I answered the same question here: https://stackoverflow.com/questions/47571144

Copy/Paste from the above link:

I had the same issue when I was making a drop-down menu and a confirmation dialog I wanted to dismiss them when clicking outside.

My final implementation works perfectly but requires some css3 animations and styling.

NOTE: i have not tested the below code, there may be some syntax problems that need to be ironed out, also the obvious adjustments for your own project!

What i did:

I made a separate fixed div with height 100%, width 100% and transform:scale(0), this is essentially the background, you can style it with background-color: rgba(0, 0, 0, 0.466); to make obvious the menu is open and the background is click-to-close. The menu gets a z-index higher than everything else, then the background div gets a z-index lower than the menu but also higher than everything else. Then the background has a click event that close the drop-down.

Here it is with your html code.

<div class="dropdownbackground" [ngClass]="{showbackground: qtydropdownOpened}" (click)="qtydropdownOpened = !qtydropdownOpened"><div>
<div class="zindex" [class.open]="qtydropdownOpened">
  <button (click)="qtydropdownOpened = !qtydropdownOpened" type="button" 
         data-toggle="dropdown" aria-haspopup="true" [attr.aria-expanded]="qtydropdownOpened ? 'true': 'false' ">
   {{selectedqty}}<span class="caret margin-left-1x "></span>
 </button>
  <div class="dropdown-wrp dropdown-menu">
  <ul class="default-dropdown">
      <li *ngFor="let quantity of quantities">
       <a (click)="qtydropdownOpened = !qtydropdownOpened;setQuantity(quantity)">{{quantity  }}</a>
       </li>
   </ul>
  </div>
 </div>

Here is the css3 which needs some simple animations.

/* make sure the menu/drop-down is in front of the background */
.zindex{
    z-index: 3;
}

/* make background fill the whole page but sit behind the drop-down, then
scale it to 0 so its essentially gone from the page */
.dropdownbackground{
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 2;
    transform: scale(0);
    opacity: 0;
    background-color: rgba(0, 0, 0, 0.466);
}

/* this is the class we add in the template when the drop down is opened
it has the animation rules set these how you like */
.showbackground{
    animation: showBackGround 0.4s 1 forwards; 

}

/* this animates the background to fill the page
if you don't want any thing visual you could use a transition instead */
@keyframes showBackGround {
    1%{
        transform: scale(1);
        opacity: 0;
    }
    100% {
        transform: scale(1);
        opacity: 1;
    }
}

If you aren't after anything visual you can just use a transition like this

.dropdownbackground{
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 2;
    transform: scale(0);
    opacity: 0;
    transition all 0.1s;
}

.dropdownbackground.showbackground{
     transform: scale(1);
}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax How to implement drop down list in flutter? How can I create a dropdown menu from a List in Tkinter? How can I close a dropdown on click outside? Making a drop down list using swift? HTML: Select multiple as dropdown How to get selected value of a dropdown menu in ReactJS Avoid dropdown menu close on click inside Bootstrap 3 dropdown select How to make a drop down list in yii2? Android custom dropdown/popup menu

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to rxjs

Angular - "has no exported member 'Observable'" What is pipe() function in Angular How to convert Observable<any> to array[] TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable What is the difference between Subject and BehaviorSubject? Best way to import Observable from rxjs take(1) vs first() Observable Finally on Subscribe Getting an object array from an Angular service BehaviorSubject vs Observable?