打开第二个时关闭下拉菜单/ document.click 被单击 Angular 5 阻止

Posted

技术标签:

【中文标题】打开第二个时关闭下拉菜单/ document.click 被单击 Angular 5 阻止【英文标题】:Close dropdown when second is opened / document.click blocked by click Angular 5 【发布时间】:2018-05-21 09:10:37 【问题描述】:

我正在尝试为下拉菜单创建一个指令,只要我使用单个下拉菜单,它就像一个魅力。我可以使用以下代码点击外部下拉菜单:

@HostListener('document:click', ['$event'])
  onDocumentClick(event: any): void 
    console.log("document click");
    // close

@HostListener('click')
  onClick(): void 
    console.log('click on ');  
    // toggle  
  

当创建了 2 个下拉菜单时会出现问题。我想在打开第二个下拉菜单时关闭第一个下拉菜单,但是当我点击第二个下拉菜单时,只有“click”事件被触发并且“document.click”没有被执行。我希望这两个事件都应该发生,除非我在点击时明确使用 preventDefault 但显然这会自动发生。

在打开第二个下拉菜单时,Angular 5 中关闭第一个下拉菜单的正确方法应该是什么?

【问题讨论】:

我尝试使用指令来实现这一点,但没有成功。每次打开或关闭下拉列表时,我都必须向组件添加一个私有属性并标记,以便在单击另一个下拉列表时考虑关闭它。我遵循了来自@J. Frankenstein 的示例代码 【参考方案1】:

也许你可以试试这样的:

 @HostListener('document:click', ['$event'])
  onClick(event) 
    if(this.eRef.nativeElement.contains(event.target)) 
      // toggle logic
     else 
      // close logic
    

因此,与其让两个事件相互冲突,不如让一个事件具有两个逻辑来准确处理您需要的内容,具体取决于您是在元素本身内部还是外部单击。说得通?

这取自here

【讨论】:

谢谢,但“内部点击”不会被触发”-> if( this._element.nativeElement.contains(event.target)) console.log('click on '); 不会不工作 您是否有错误或根本没有进入 if? 我的错,当我点击下拉菜单时,这根本不会被触发。我把控制台日志放在它之前,当我点击下拉菜单时它没有被触发。【参考方案2】:

创建一个可以在任何地方使用的指令怎么样?

@Directive( 
    selector : '[clicked-outside]' ,
    host     : 
        '(document:click)' : 'onClick($event)',
        '(document:touch)' : 'onClick($event)',
        '(document:touchstart)' : 'onClick($event)'
     
 )
export class ClickedOutsideDirective 
    @Input( 'clicked-outside' ) callback : Function;

    constructor ( private _el : ElementRef ) 
    

    private onClick ( event : any ) 
        if ( this.clickedOutside( event ) ) 
            if ( this.callback ) 
                this.callback();
            
        
    

    private clickedOutside ( event : any ) 
        let clickedTarget = event.target;
        let host          = this._el.nativeElement;
        do 
            if ( clickedTarget === host ) 
                return false;
            
            clickedTarget = clickedTarget.parentNode;
         while ( clickedTarget );
        return true;
    

你可以这样使用它:

@Component(
   selector:'your-dropdown',
   template:`
       <div class="your-dropdown-top-most-wrapper" [clicked-outside]="onClickOutSide"></div>

   `
)
export class YouDropdownComponent


   public onClickOutSide = ()=>


        this.closeMyDropdown()// this is your function that closes the dropdown
   

【讨论】:

以上是关于打开第二个时关闭下拉菜单/ document.click 被单击 Angular 5 阻止的主要内容,如果未能解决你的问题,请参考以下文章

单击第二个下拉列表时,黑框应保持可见

多级下拉引导

下拉菜单无法正常工作

第一个下拉菜单更改第二个下拉菜单相关项目显示

为啥我的第二个下拉菜单是复制我的第一个下拉菜单的更改操作

第一个下拉菜单自动更改第二个下拉菜单的选项