我创建了一个用于拖放的自定义指令,我不使用角度材质的拖放,因为只能垂直或水平拖动。 问题在于移动触摸,对于
touchstart
和 touchend
,目标是相同的。
import { Directive, EventEmitter, HostListener, Output } from '@angular/core';
@Directive({
selector: '[appDragAndDrop]',
standalone: true,
})
export class DragAndDropDirective {
@Output() itemDrop = new EventEmitter<{ draggedIndex: number, targetIndex: number }>();
@HostListener('touchstart', ['$event'])
onTouchStart(event: TouchEvent) {
const touch = event.touches[0];
const target = touch.target as HTMLElement;
const dataIndex = target.getAttribute('data-index');
if (dataIndex) {
target.dataset['draggedIndex'] = dataIndex;
}
}
@HostListener('touchmove', ['$event'])
onTouchMove(event: TouchEvent) {
event.preventDefault();
}
@HostListener('touchend', ['$event'])
onTouchEnd(event: TouchEvent) {
const target = event.target as HTMLElement;
const targetIndex = +target.getAttribute('data-index');
const draggedIndex = +(target.dataset['draggedIndex'] || '');
if (!Number.isNaN(draggedIndex) && !Number.isNaN(targetIndex)) {
this.itemDrop.emit({ draggedIndex, targetIndex });
}
}
}
需要帮助,如果存在其他解决方案或显示我做错了什么。
您可能需要实现一种方法来跟踪拖动过程中的移动。 例如:
private lastTouchX: number = 0;
private lastTouchY: number = 0;
onTouchStart(event: TouchEvent) {
//Your code
if (dataIndex) {
target.dataset['draggedIndex'] = dataIndex;
this.lastTouchX = touch.clientX;
this.lastTouchY = touch.clientY;
}
}
onTouchMove(event: TouchEvent) {
//your code
const touch = event.touches[0];
this.lastTouchX = touch.clientX;
this.lastTouchY = touch.clientY;
}
onTouchEnd(event: TouchEvent) {
const target = document.elementFromPoint(this.lastTouchX, this.lastTouchY) as HTMLElement;
const draggedIndex = +(event.target as HTMLElement).dataset['draggedIndex'] || '';
//...
delete (event.target as HTMLElement).dataset['draggedIndex'];
}
}