用户单击外部时关闭以下下拉列表

时间:2017-04-26 12:18:16

标签: angular typescript

我有一个下拉列表,我想在用户点击下拉列表时关闭它。

<div  [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>

我尝试使用Angular2 Close dropdown on click outside, is there an easiest way?方法,但它似乎无效。

预期行为 下拉列表应该关闭。

实际行为 它仍然开放。

3 个答案:

答案 0 :(得分:1)

我认为你有两种选择。第一个是使div内容可编辑(或使用另一个具有模糊事件的元素)并添加一个模糊事件的监听器来隐藏drowdown。当元素失去焦点(如点击外部等)时,将触发模糊。

或者您可以向组件添加窗口侦听器,并在下拉列表外单击时隐藏它:

@Component({
  selector: 'mySelector',
  template : 'YourTemplatehere',
  host: {'(window:mouseup)': 'handleMouseUp($event)'},
})

export class MyClass {
  handleMouseUp(e: MouseEvent) {
    // Your code to handle the hiding logic. I think in your case its;
    this.qtydropdownOpened = !this.qtydropdownOpened;
  }
}

答案 1 :(得分:1)

<div>
  <button  (click)="myFunction()" 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" #myDropdown>
  <ul class="default-dropdown">
      <li *ngFor="let quantity of quantities">
       <a (click)="qtydropdownOpened = !qtydropdownOpened;setQuantity(quantity)">{{quantity  }}</a>
       </li>
   </ul>
  </div>
 </div>

在您的组件

@Component({
        templateUrl: 'header.html'
        host: {
            '(document:click)': 'onClick($event)'
        }
})
export class DropDownComponent{
@ViewChild('myDropdown') myDropdown: ElementRef;
    public myFunction() {
      this.myDropdown.nativeElement.classList.toggle("show")
    }
 // Close the dropdown if the user clicks outside of it
onClick(event) {
    if (!event.target.matches('.dropbtn')) {

        var dropdowns = this.myDropdown.nativeElement;
        if (dropdowns.classList.contains('show')) {
            dropdowns.classList.remove('show');
        }
    }
 }
}

答案 2 :(得分:1)

我在制作下拉菜单和确认对话框时遇到了同样的问题,我想在外面点击时将其解雇。

我的最终实现完美无缺,但需要一些css3动画和样式。

注意:我还没有测试下面的代码,可能会有一些需要解决的语法问题,也是对你自己项目的明显调整!

我做了什么:

我制作了一个单独的固定div,高度为100%,宽度为100%,变换:scale(0),这实际上是背景,你可以用背景颜色设置它:rgba(0,0,0,0.466) ;显而易见,菜单是打开的,背景是点击关闭。 菜单获得的z-index高于其他所有菜单,然后背景div获得的z-index低于菜单,但也高于其他所有菜单。然后,后台有一个关闭下拉列表的点击事件。

这是你的HTML代码。

<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>

这是需要一些简单动画的css3。

/* 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;
    }
}

如果您没有视觉效果,可以使用此类转换

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

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