如何获取mat-menu打开后的位置并检测其位置变化?
方案1:直接利用Material自带的样式类(无需JS)
Angular Material在mat-menu渲染时,会自动根据展开位置给菜单面板添加对应的位置类:
- 向下展开时添加
mat-menu-below类 - 向上展开时添加
mat-menu-above类 mat-menu-before、mat-menu-after对应左右方向的位置
你可以直接用这些类写自定义样式:
/* 向上展开的菜单样式 */ .mat-menu-panel.mat-menu-above { border-radius: 4px 4px 0 0; border-bottom: none; } /* 向下展开的菜单样式 */ .mat-menu-panel.mat-menu-below { border-radius: 0 0 4px 4px; border-top: none; }
如果需要在TS代码中获取位置状态、执行自定义逻辑,使用方案2。
方案2:TS代码监听位置变更
步骤1:给mat-menu加模板引用,同时监听打开事件
<button mat-button [matMenuTriggerFor]="menu">打开菜单</button> <mat-menu #menu="matMenu" (menuOpened)="onMenuOpened()"> <button mat-menu-item>选项1</button> <button mat-menu-item>选项2</button> </mat-menu>
步骤2:在TS中获取菜单实例,监听overlay位置变化
import { ViewChild, OnDestroy } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; import { Subscription } from 'rxjs'; @Component({ // 你的组件配置 }) export class YourComponent implements OnDestroy { @ViewChild('menu') menu: MatMenu; private positionChangeSub: Subscription | null = null; onMenuOpened() { // 清理之前的订阅避免内存泄漏 this.positionChangeSub?.unsubscribe(); // 监听overlay位置变化事件 this.positionChangeSub = this.menu.overlayRef?.positionChanges.subscribe(pos => { // 解析位置信息 const isAbove = pos.connectionPair.originY === 'bottom' && pos.connectionPair.overlayY === 'top'; const isBelow = pos.connectionPair.originY === 'top' && pos.connectionPair.overlayY === 'bottom'; // 执行你需要的业务逻辑 console.log('菜单是否向上展开:', isAbove); console.log('菜单是否向下展开:', isBelow); }); } ngOnDestroy() { this.positionChangeSub?.unsubscribe(); } }
注意事项
- 如果你使用的是Angular Material 15+的MDC版本,样式类前缀改为
mdc-menu,对应位置类为mdc-menu--open-above、mdc-menu--open-below - 首次打开的位置可以直接在
menuOpened事件中调用this.menu.overlayRef.getOverlayElement().getBoundingClientRect(),对比触发元素的坐标判断位置
内容的提问来源于stack exchange,提问作者MargeKh
相关产品推荐
相关产品推荐

