Angular12中右键触发Mat Menu始终显示在浏览器左上角如何修复
修复方案
你遇到的问题根源有三个:
- Mat Menu默认相对于
MatMenuTrigger绑定的元素定位,你当前绑定trigger的是固定定位的隐藏div,右键点击时没有更新这个div的坐标,导致菜单始终以初始位置(浏览器左上角)为基准弹出 - 你定义的
menuTopLeftPosition变量没有和菜单的定位属性绑定,赋值后不会生效 - HTML结构错误:
mat-cell必须是列定义ng-container的直接子元素,包裹在div中会导致表格渲染异常
步骤1:调整HTML代码
修正表格结构,同时调整trigger和菜单的绑定逻辑:
<mat-drawer-content> <div style="height: 500px;"> <mat-table [dataSource]="this.backlogservice.backlogIssues" class="mat-elevation-z8" cdkDropList #tablebacklog #listbacklog="cdkDropList" [cdkDropListData]="this.backlogservice.backlogIssues" cdkDropList [cdkDropListConnectedTo]="this.getConnected()" style="cursor: move" (cdkDropListDropped)="drop($event, null)" id="tablebacklog"> <ng-container matColumnDef="task" style="width: 10%"> <mat-header-cell *matHeaderCellDef> Task </mat-header-cell> <mat-cell *matCellDef="let element"> <mat-icon (click)="showTasks(element)" style="cursor: pointer; color: #F70000;">exit_to_app</mat-icon> </mat-cell> </ng-container> <ng-container matColumnDef="orderby" style="width: 10%"> <mat-header-cell style="font-weight: bold;" *matHeaderCellDef> No. </mat-header-cell> <mat-cell *matCellDef="let element; let i=index"> {{i}} </mat-cell> </ng-container> <ng-container matColumnDef="title" style="width: 40%"> <mat-header-cell style="font-weight: bold;" *matHeaderCellDef> Title </mat-header-cell> <!-- 修正mat-cell层级,右键事件直接绑定在cell上 --> <mat-cell *matCellDef="let element" (contextmenu)="onRightClick($event, {content: element})"> {{element.title}} </mat-cell> </ng-container> </mat-table> </div> <!-- 隐藏的trigger移到表格外,单独定义 --> <div #menuTrigger="matMenuTrigger" [matMenuTriggerFor]="sendToMenu" style="visibility: hidden; position: fixed; pointer-events: none;" ></div> <!-- 你的菜单定义,可根据需要调整偏移 --> <mat-menu #sendToMenu="matMenu" yPosition="below" xPosition="before"> <!-- 菜单内容示例 --> <button mat-menu-item *ngFor="let item of menuData.item"> {{item.content.title}} </button> </mat-menu> </mat-drawer-content>
步骤2:修改组件类代码
获取trigger的DOM引用,右键点击时先更新trigger的坐标再打开菜单:
export class BacklogComponent implements OnInit { @ViewChild('menuTrigger') matMenuTrigger!: MatMenuTrigger; // 新增:获取trigger对应的DOM元素引用 @ViewChild('menuTrigger', { read: ElementRef }) menuTriggerEl!: ElementRef<HTMLElement>; menuData: any; constructor( private dataSvc: DataService, private kc: KeycloakService, public backlogservice: BacklogService, public _issueService: IssuesService, private changeDetectorRef: ChangeDetectorRef, public sprints: SprintService, public modalService: ModalService ) { } ngOnInit() {} onRightClick(event: MouseEvent, item: any) { event.preventDefault(); // 将隐藏trigger的位置设置为鼠标点击的视口坐标 this.menuTriggerEl.nativeElement.style.left = `${event.clientX}px`; this.menuTriggerEl.nativeElement.style.top = `${event.clientY}px`; this.matMenuTrigger.menuData = {item: item}; // 触发变更检测确保位置更新后再打开菜单 this.changeDetectorRef.detectChanges(); this.matMenuTrigger.openMenu(); } }
如果需要调整菜单和点击位置的相对偏移,可以修改clientX/clientY的数值,比如${event.clientX - 10}px避免菜单完全覆盖鼠标。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

