【问题标题】:Angular Material - hide menu on button's mouseleaveAngular Material - 在按钮的 mouseleave 上隐藏菜单
【发布时间】:2018-11-21 09:31:50
【问题描述】:

我得到了在按钮的mouseenter 事件上显示的菜单。工具栏中的所有内容:

<mat-toolbar color="primary">
  <button mat-button routerLink="/products" [matMenuTriggerFor]="menu1"
      #matMenu1Trigger="matMenuTrigger"
      (mouseenter)="matMenu1Trigger.openMenu()">Menu1
  </button>
  <mat-menu #menu1="matMenu">
    <div (mouseleave)="matMenu1Trigger.closeMenu()">
      <button mat-menu-item>Item 1</button>
    </div>
  </mat-menu>
</mat-toolbar>

菜单在mouseleave 周围跨度事件时关闭,到目前为止一切顺利。 现在我想通过添加来关闭触发按钮的mouseleave 上的菜单

(mouseleave)="matMenu1Trigger.closeMenu()"

当我这样做并将鼠标移到此按钮上时,菜单开始闪烁,就像每隔几毫秒打开/关闭一次。

为什么会这样?当鼠标离开按钮时如何隐藏菜单?

https://stackblitz.com/edit/angular-kd8bue

编辑:经过一番谷歌搜索后,我发现此行为是由打开菜单时显示的叠加层引起的,如How to open mat-menu on a single click and close other opened menu if there is any? 所述。由于覆盖,我不确定我想要实现的目标是否可能......

【问题讨论】:

  • 你想用css而不是javascript试试这个吗?
  • 尝试将菜单的 opened 值绑定到组件打字稿变量,并从事件中更改该值。例如:(HTML)&lt;mat-menu #menu1="matMenu" [opened]="varOpened"&gt;(TYPESCRIPT):var varOpened: boolean = false;(HTML) :&lt;div (mouseleave)="closeMenu()"&gt;(打字稿):closeMenu(){ this.varOpened=false; }。我没有测试过,但我以前总是这样处理 Angular Material 的东西,所以......让我知道它是否有效!
  • @Deadpool:没有opened这样的属性,见material.angular.io/components/menu/api

标签: javascript html angular angular-material


【解决方案1】:

请在 github 上查看这个已关闭的问题

https://github.com/angular/material2/issues/10378#issuecomment-372626596

当您的mouseenter 打开mat-menu... 时,会创建一个cdkOverlay 并将焦点设置为mat-menu cdkOverlay,这会立即触发您的mouseleave 事件,因为焦点现在位于覆盖而不是您的按钮上。 .. 即使您的鼠标仍在按钮上。


修订

请查看我为这个 SO 答案所做的以下 stackblitz。

How to open and close Angular mat menu on hover

https://stackblitz.com/edit/mat-nested-menu-yclrmd?embed=1&file=app/nested-menu-example.html

【讨论】:

  • 感谢您的解释,这就是我一直在寻找的,了解为什么会发生这种情况。解决方法,是的,不是真的,但无论如何谢谢。
  • 干得好!可惜没有内置这样的基本功能。也许使用第三方组件?
【解决方案2】:
    <mat-toolbar color="primary">
        <button   mat-button >Menu0 </button>

        <button mat-button routerLink="/products" [matMenuTriggerFor]="menu1"
        #matMenu1Trigger="matMenuTrigger"
        (mouseenter)="buttonenter()"
        (mouseout)="buttonleave()" style=" z-index: 50000">Menu1
        </button>
        <mat-menu #menu1="matMenu" >
          <div (mouseleave)="matMenu1Trigger.closeMenu()"
          (mouseenter)="menuenter()"
          >
        <button mat-menu-item>Item 1</button>
        <button mat-menu-item>Item 2</button>
        <button mat-menu-item>Item 3</button>
        <button mat-menu-item>Item 4</button>
        <button mat-menu-item>Item 5</button>
        <button mat-menu-item>Item 6</button>        
          </div>
        </mat-menu>

          <button   mat-button >MenuX </button>


          <button mat-button routerLink="/products" [matMenuTriggerFor]="menu2"
        #matMenu1Trigger2="matMenuTrigger"
        (mouseenter)="buttonenter2()"
        (mouseout)="buttonleave2()" style=" z-index: 50000">Menu2
        </button>
        <mat-menu #menu2="matMenu" >
          <div (mouseleave)="matMenu1Trigger2.closeMenu()"
           (mouseenter)="menuenter2()"
          >
        <button mat-menu-item>Item2 1</button>
        <button mat-menu-item>Item2 2</button>
        <button mat-menu-item>Item2 3</button>
        <button mat-menu-item>Item2 4</button>
        <button mat-menu-item>Item2 5</button>
        <button mat-menu-item>Item2 6</button>          

          </div>
        </mat-menu>

          <button   mat-button >Menu3 </button>
          <button   mat-button >Menu4 </button>
          <button   mat-button >Menu5 </button>
          <button   mat-button >Menu6 </button>


      </mat-toolbar>


    import { Component, ViewChild } from '@angular/core';

    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {

      name = 'Angular';
      isEnterMatMenuOpen = false;
      @ViewChild('matMenu1Trigger') _matMenu1Trigger
      @ViewChild('menuButton') _menuButton

      isEnterMatMenuOpen2 = false;
      @ViewChild('matMenu1Trigger2') _matMenu1Trigger2
      @ViewChild('menuButton2') _menuButton2

      buttonenter() {
          this._matMenu1Trigger.openMenu();
          this.isEnterMatMenuOpen = false;
      }
      menuenter() {
          this.isEnterMatMenuOpen = true;
      }
      buttonleave() {
        setTimeout(() => {
        if( !this.isEnterMatMenuOpen ) this._matMenu1Trigger.closeMenu();
        }, 50);
      }

      buttonenter2() {
           this._matMenu1Trigger2.openMenu();  
          this.isEnterMatMenuOpen2 = false; 
      }
      menuenter2() {
          this.isEnterMatMenuOpen2 = true;
      }
      buttonleave2() {
        setTimeout(() => {
        if( !this.isEnterMatMenuOpen2 ) this._matMenu1Trigger2.closeMenu();
        }, 50);
      } 

    }

【讨论】:

  • 上面的代码可以用来悬停和离开有角度的材质菜单项。关键是: style=" z-index: 50000" 让它工作。这是该概念的粗略测试代码。如果你想使用它,你必须让代码看起来不错。
  • 这看起来不错,但只是乍一看。其次,有时由于菜单关闭,鼠标无法进入菜单。此外,当我将指针从按钮移动到新打开的菜单并尝试移回按钮时,第二个菜单重复弹出就在打开的菜单旁边。没想到 Angular Material 会出现这样的菜单……尤其是与 mdbootstrap.comprimefaces.org/primeng/# 等竞争对手相比
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
相关资源
最近更新 更多