You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:06:08