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

如何在Angular中实现元素的水平与垂直双向拖拽?

解决Angular CDK Drag Drop流式布局下的自由拖拽问题

要实现元素换行时同时支持水平和垂直方向的拖拽排序,你需要结合CSS流式布局和自定义CDK拖拽排序逻辑,具体步骤如下:

1. 调整HTML结构

移除cdkDropListOrientation属性,添加自定义排序函数绑定:

<div class="list"
     cdkDropList
     #todoList="cdkDropList"
     [cdkDropListData]="completed"
     [cdkDropListConnectedTo]="[doneList]"
     [cdkDropListSortingFn]="customSortingFn"
     (cdkDropListDropped)="onDrop($event)">
              
  <ng-container *ngFor="let option of completed; let i = index">
   <div class="mat-card" cdkDrag>
    <p>{{option.name}}</p>
   </div>
  </ng-container>

</div>

注意:你的原代码中*ngFor遍历的是options数组,但定义的数据源是completed,这里需要修正为completed。

2. 设置CSS流式布局

给列表容器添加样式,让元素自动换行排列:

.list {
  display: flex;
  flex-wrap: wrap;
  gap: 16px; /* 元素间距 */
  padding: 16px;
}

.mat-card {
  padding: 12px 24px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  min-width: 120px;
}

3. 实现自定义排序函数

在组件TS文件中添加customSortingFn,根据拖拽元素的坐标计算正确的插入位置:

import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';

// ...

completed = [
  { name: 'HTML' },
  { name: 'CSS' },
  { name: 'Angular' },
  { name: 'React' },
  { name: 'Vue' }
];

customSortingFn = (a: CdkDrag, b: CdkDrag) => {
  const aRect = a.element.nativeElement.getBoundingClientRect();
  const bRect = b.element.nativeElement.getBoundingClientRect();
  
  // 先比较垂直位置(y轴),再比较水平位置(x轴)
  if (aRect.y !== bRect.y) {
    return aRect.y - bRect.y;
  }
  return aRect.x - bRect.x;
};

onDrop(event: CdkDragDrop<any[]>) {
  if (event.previousContainer === event.container) {
    moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
  } else {
    // 跨容器拖拽的逻辑(如果需要)
    transferArrayItem(
      event.previousContainer.data,
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
  }
}

原理说明

  • 移除cdkDropListOrientation后,CDK默认使用垂直排序逻辑,但我们通过CSS让元素横向流式排列。
  • 自定义排序函数customSortingFn会同时参考元素的垂直(y轴)和水平(x轴)位置,确保拖拽时插入到正确的位置,适配换行后的布局。
  • 流式布局下元素会自动换行,拖拽时CDK会根据排序函数的结果更新数组顺序,从而同步DOM的排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:45:48