如何在鼠标悬停时显示Angular Material下拉菜单?

6
现在,当我点击汉堡菜单时,我会得到下拉列表,但我需要在鼠标悬停在汉堡菜单上时显示它。这是 Stack Blitz 的链接: link
图片链接如下:enter image description here
7个回答

23
你可以使用 matMenuTrigger 指令来完成此操作。
<button mat-icon-button [matMenuTriggerFor]="menu" 
    #menuTrigger="matMenuTrigger" (mouseenter)="menuTrigger.openMenu()">

要隐藏菜单,请为菜单添加 mouseleave 事件。

将所有菜单项捆绑在一个 spandiv 标签内。然后将 (mouseleave) 事件附加到其中。

<mat-menu #menu="matMenu" [overlapTrigger]="false">
    <span (mouseleave)="menuTrigger.closeMenu()">
      <button mat-menu-item>
        <mat-icon>home</mat-icon>
        <span>Home</span>
        ........
       <mat-icon>exit_to_app</mat-icon>
       <span>Logout</span>
     </button>
    </span>
</mat-menu>

分叉自演示


当鼠标移出时,下拉菜单应该消失。 - PGH
@PrashanthGH 为 (mouseleave) 添加另一个事件绑定。 - Our_Benefactors
@Amit chigadani,我添加了(mouseleave)事件,但它没有正常工作。这是Stack Blitz的链接:https://stackblitz.com/edit/example-angular-material-toolbar-menu-fenxju?file=app/app.component.html - PGH
@PrashanthGH 你好,请检查更新的答案和演示。 - Amit Chigadani
2
这应该是 StackOverflow 中的第一个链接。 - Pavan Jadda

6

我知道我很晚才加入这个行列,但以上内容都不太适用于我。最终,我编写了一个指令来解决这个问题。

HoverDropDownDirective(悬停下拉指令)

import { NgModule } from '@angular/core';
import { Directive, Input, ElementRef, OnInit } from '@angular/core';
import { MatMenuTrigger, _MatMenu } from '@angular/material';

@Directive({
    selector: '[hoverDropDown]'
})
export class HoverDropDownDirective implements OnInit {
    isInHoverBlock = false;

    constructor(private el: ElementRef) {}

    @Input() hoverTrigger: MatMenuTrigger;
    @Input() menu: any;

    ngOnInit() {
        this.el.nativeElement.addEventListener('mouseenter', () => {
            this.setHoverState(true);
            this.hoverTrigger.openMenu();

            const openMenu = document.querySelector(`.mat-menu-after.${this.menu._elementRef.nativeElement.className}`);
            if (!openMenu) {
                this.hoverTrigger.closeMenu();
                return;
            }
            openMenu.addEventListener('mouseenter', () => {
                this.setHoverState(true);
            });
            openMenu.addEventListener('mouseleave', () => {
                this.setHoverState(false);
            });
        });
        this.el.nativeElement.addEventListener('mouseleave', () => {
            this.setHoverState(false);
        });
    }

    private setHoverState(isInBlock: boolean) {
        this.isInHoverBlock = isInBlock;
        if (!isInBlock) {
            this.checkHover();
        }
    }

    private checkHover() {
        setTimeout(() => {
            if (!this.isInHoverBlock && this.hoverTrigger.menuOpen) {
                this.hoverTrigger.closeMenu();
            }
        }, 50);
    }
}

@NgModule({
    declarations: [
        HoverDropDownDirective
    ],
    exports: [
        HoverDropDownDirective
    ]
})
export class HoverDropDownDirectiveModule {}

app.module

import { HoverDropDownDirectiveModule } from '../../directives/hover-drop-down.directive';

imports: [
    HoverDropDownDirectiveModule
]

HTML

<div *ngFor="let category of categories">
    <button #menuTrigger="matMenuTrigger"
            mat-button
            [matMenuTriggerFor]="children"
            (click)="navigateMain(category.Category)"

            hoverDropDown
            [menu]="children"
            [hoverTrigger]="menuTrigger">
             {{category.Category.Description}}
    </button>
    <mat-menu #children="matMenu" hasBackdrop="false">
        <button mat-menu-item *ngFor="let sub of category.SubCategories" (click)="navigateSubCategory(sub)">{{sub.Description}}</button>
    </mat-menu>
</div>

需要注意两件事情:

  1. Main Button中的3个属性("hoverDropDown"、"[menu]"和"[hoverTrigger]")
  2. mat-menu中的hasBackdrop="false"属性

hasBackdrop="false"属性在Angular Material文档中有详细说明。希望这对你有帮助...


适用于多个菜单,非常好用。 - Jay Ordway
我将尝试为一个小子菜单测试这个。 - Willie
对我来说,这比被接受的答案更好用。谢谢。 - Mitchell Brooks

1
为 mat 按钮添加一个引用变量,用于在鼠标悬停事件上触发 click。请保留 HTML 标签。
<button mat-icon-button
        #matBtn
        (mouseover)="matBtn._elementRef.nativeElement.click()"
        [matMenuTriggerFor]="menu"
>

注意:我不太喜欢像这样访问对象的“私有”属性,我的解决方案更像是一个变通方法,请在找不到其他方法时使用。

1

1

覆盖 mouseover 事件并创建 #menuTrigger 引用变量。这将解决您的问题。

  <button mat-icon-button [matMenuTriggerFor]="menu" #menuTrigger="matMenuTrigger" 
  (mouseover)="menuTrigger.openMenu()" >

我已经更新了你的 stackblitz

如果有多个菜单,这是不起作用的。无论如何,我已经投票了。 - Sathiamoorthy

0

0

app.component.html:

<mat-toolbar color="primary" >
  <span class="fill-remaining-space">
    <button #clickMe mat-icon-button [matMenuTriggerFor]="menu" (mouseenter)="clickOnHover()">
      <mat-icon>menu</mat-icon>
    </button>
    <mat-menu #menu="matMenu" [overlapTrigger]="false">
      <button mat-menu-item>
        <mat-icon>home</mat-icon>
        <span>Home</span>
      </button>
      <button mat-menu-item>
        <mat-icon>people_outline</mat-icon>
        <span>Connecting</span>
      </button>
      <button mat-menu-item>
        <mat-icon>videocam</mat-icon>
        <span>Let's talk</span>
      </button>
      <button mat-menu-item>
        <mat-icon>exit_to_app</mat-icon>
        <span>Logout</span>
      </button>
    </mat-menu>
  </span>
  <span class="fill-remaining-space">Application Title</span>
</mat-toolbar>

app.component.ts:

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


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

  clickOnHover() {
    this.clickMe._elementRef.nativeElement.click();
  }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接