简体   繁体   English

单击外部时如何阻止 angular mat-menu 关闭?

[英]How to stop angular mat-menu from closing when you click outside of it?

I'm using MatMenu as a popup to tour around new users on my web app so I don't want to dismiss it whenever the user clicks outside of it.我使用 MatMenu 作为弹出窗口来浏览我的 web 应用程序上的新用户,所以我不想在用户点击它外部时将其关闭。

I've already used used $event.stopPropagation() to stop it from closing when I click a button inside it.当我单击其中的按钮时,我已经使用 $event.stopPropagation() 来阻止它关闭。 Now I want to know how to keep it open even if you click outside of it.现在我想知道如何保持打开状态,即使你在外面点击。

The click is handled by the overlay backdrop.点击由覆盖背景处理。 You can apply/remove classes to the backdrop dynamically based on your menu open and close, and defeat the backdrop click using CSS withpointer-events .您可以根据您的菜单打开和关闭动态地将类应用/删除到背景,并使用带有pointer-events的 CSS 击败背景点击。

For example:例如:

HTML HTML

<button mat-button [matMenuTriggerFor]="menu" (menuOpened)="preventCloseOnClickOut()" (menuClosed)="allowCloseOnClickOut()">Menu</button>

TS TS

export class MenuOverviewExample {
  constructor(private overlayContainer: OverlayContainer) {}

  preventCloseOnClickOut() {
    this.overlayContainer.getContainerElement().classList.add('disable-backdrop-click');
  }

  allowCloseOnClickOut() {
    this.overlayContainer.getContainerElement().classList.remove('disable-backdrop-click');
  }
}

Global CSS全球 CSS

.disable-backdrop-click .cdk-overlay-backdrop.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing {
  pointer-events: none;
}

i think [hasBackdrop]="false" and [hasBackdrop]="true" can handle that我认为 [hasBackdrop]="false" 和 [hasBackdrop]="true" 可以处理

You can wrap around the mat-menu-items if you are trying to stop propagating the whole menu.如果您试图停止传播整个菜单,您可以环绕 mat-menu-items。

<mat-menu [hasBackdrop]="false">
     <div  (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()">
       <your-app></your-app>
     </div>
</mat-menu>

I had the same problem, I had need a validation and as result the outside click (on backdrop) shouldn't effect.我有同样的问题,我需要验证,结果外部点击(背景)不应该影响。 Remove the backdrop events with pointer-events allows interactions in all behind element, my solution was create a clone of backdrop and remove the listeners of this clone.使用指针事件删除背景事件允许在所有后面的元素中进行交互,我的解决方案是创建背景的克隆并删除此克隆的侦听器。

    avoidClickOutside() {
      const overlayers = this.overlay
      .getContainerElement()
      .querySelectorAll('.controlled');

      if (overlayers && this.isAvoidClickOutside) {
        overlayers.forEach((element) => {
          const clone = element.cloneNode(true);
          (clone as Element).classList.add('clone');
          clone.addEventListener('click', (event: Event) => {
            if (confirm('Not allowed... Do you want remove this behaviour?!')) {
              this.removeCloneBackdrop();
            }
          });
          element.parentNode.insertBefore(clone, element.nextSibling);
        });
      }
   }

isAvoidClickOutside is my control variable to either avoid or not. isAvoidClickOutside 是我要避免或不避免的控制变量。

Available: https://stackblitz.com/edit/angular-yjvkft可用: https://stackblitz.com/edit/angular-yjvkft

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM