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

如何获取Angular中cdkDrag子组件拖拽后的新位置

获取Angular CDK Drag组件拖拽后的位置信息

Angular CDK Drag本身封装了完整的拖拽逻辑,不用自己处理pointerdown/pointermove/pointerup这些原生事件,通过它的内置事件和API就能轻松获取拖拽后的位置,下面是两种可行方案:

方案一:子组件传递拖拽结束事件

因为app-elementA和app-elementB内部是cdkDrag元素,你可以在子组件里监听cdkDragEnded事件,把位置信息传递给父组件:

1. 修改子组件(以ElementAComponent为例)

<!-- element-a.component.html -->
<div cdkDrag (cdkDragEnded)="handleDragEnd($event)">
  <!-- 子组件内容 -->
</div>
// element-a.component.ts
import { Component, Output, EventEmitter } from '@angular/core';
import { CdkDragEnd } from '@angular/cdk/drag-drop';

@Component({
  selector: 'app-elementA',
  templateUrl: './element-a.component.html'
})
export class ElementAComponent {
  @Output() dragEnd = new EventEmitter<CdkDragEnd>();

  handleDragEnd(event: CdkDragEnd) {
    this.dragEnd.emit(event);
  }
}

2. 父组件监听事件并获取位置

<!-- app.component.html -->
<div class="example-boundary">
  @for (item of AComponent; track item; let AIdx = $index) {
    <app-elementA
      id="{{AIdx}}"
      (dragEnd)="onADragFinish($event, AIdx)"
    ></app-elementA>
  }
  @for (item of BComponent; track item; let BIdx = $index) {
    <app-elementB
      id="{{BIdx}}"
      (dragEnd)="onBDragFinish($event, BIdx)"
    ></app-elementB>
  }
</div>
// app.component.ts
import { CdkDragEnd } from '@angular/cdk/drag-drop';

// ...

onADragFinish(event: CdkDragEnd, index: number) {
  // 获取相对于拖拽边界的坐标
  const relativePos = event.source.getFreeDragPosition();
  console.log(`A组件 ${index} 拖拽后相对位置:`, relativePos);

  // 如果需要相对于文档的绝对位置
  const domRect = event.source.element.nativeElement.getBoundingClientRect();
  const absolutePos = {
    x: domRect.left + window.scrollX,
    y: domRect.top + window.scrollY
  };
  console.log(`A组件 ${index} 拖拽后绝对位置:`, absolutePos);
}

onBDragFinish(event: CdkDragEnd, index: number) {
  const relativePos = event.source.getFreeDragPosition();
  console.log(`B组件 ${index} 拖拽后相对位置:`, relativePos);
}

方案二:父组件直接获取所有CDK Drag实例

如果不想改动子组件,可在父组件中通过ViewChildren获取所有CdkDrag实例,监听它们的结束事件:

// app.component.ts
import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
import { CdkDrag } from '@angular/cdk/drag-drop';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements AfterViewInit {
  @ViewChildren(CdkDrag) dragComponents!: QueryList<CdkDrag>;

  ngAfterViewInit() {
    this.dragComponents.forEach((dragComp, idx) => {
      dragComp.ended.subscribe(event => {
        const relativePos = dragComp.getFreeDragPosition();
        // 通过元素标签区分A/B组件
        const compType = dragComp.element.nativeElement.tagName.includes('APP-ELEMENTA') ? 'A' : 'B';
        console.log(`${compType}组件 ${idx} 拖拽后位置:`, relativePos);
      });
    });
  }
}

注意事项

  • getFreeDragPosition()返回的是相对于拖拽容器(你的.example-boundary)的坐标;若需绝对位置,用getBoundingClientRect()结合滚动偏移计算即可。
  • 优先使用CDK提供的内置事件,比原生pointer事件更适配拖拽逻辑,避免出现兼容问题。

内容的提问来源于stack exchange,提问作者user6781

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:19:53