Files
cody-crm/frontend/packages/lib-shared/method/setupDrag.ts
wangziqi 72e2110987
Some checks failed
Synchronize to Gitee / repo-sync (push) Has been cancelled
Typos Checking / Spell Check with Typos (push) Has been cancelled
chore: initial commit
2026-06-23 11:56:23 +08:00

114 lines
3.5 KiB
TypeScript

interface DragPosition {
startX: number;
startY: number;
startLeft: number;
startTop: number;
}
export function setupDrag(dragElement: HTMLElement | null) {
if (!dragElement) return;
let isDragging = false;
let dragPosition: DragPosition;
const moveHandler = (clientX: number, clientY: number) => {
dragElement.style.cursor = 'grabbing';
// 移动超过5px才认为是拖动
if (!isDragging && (Math.abs(clientX - dragPosition.startX) > 5 || Math.abs(clientY - dragPosition.startY) > 5)) {
isDragging = true;
}
if (isDragging) {
// 计算新位置
const newLeft = dragPosition.startLeft + clientX - dragPosition.startX;
const newTop = dragPosition.startTop + clientY - dragPosition.startY;
// 边界检查(可选) - 确保元素不会移出视口
const maxX = window.innerWidth - dragElement.offsetWidth;
const maxY = window.innerHeight - dragElement.offsetHeight;
// 设置新位置(限制在边界内)
dragElement.style.left = `${Math.max(0, Math.min(newLeft, maxX))}px`;
dragElement.style.top = `${Math.max(0, Math.min(newTop, maxY))}px`;
dragElement.style.right = 'auto';
dragElement.style.bottom = 'auto';
}
};
// 鼠标/触摸移动处理
const move = (e: MouseEvent | TouchEvent) => {
e.preventDefault();
if (e instanceof MouseEvent) {
moveHandler(e.clientX, e.clientY);
} else if (e.touches?.[0]) {
moveHandler(e.touches[0].clientX, e.touches[0].clientY);
}
};
// 停止拖动
const stopDrag = () => {
document.removeEventListener('mousemove', move);
document.removeEventListener('touchmove', move);
document.removeEventListener('mouseup', stopDrag);
document.removeEventListener('touchend', stopDrag);
dragElement.style.cursor = 'pointer';
// 如果是拖拽操作(不是点击),则阻止接下来的点击事件
if (isDragging) {
const clickHandler = (e: Event) => {
e.stopImmediatePropagation();
e.preventDefault();
dragElement.removeEventListener('click', clickHandler);
};
dragElement.addEventListener('click', clickHandler, true);
// 300ms后移除点击拦截
setTimeout(() => {
dragElement.removeEventListener('click', clickHandler, true);
}, 300);
}
};
// 开始拖动 - 鼠标事件
const startMouseDrag = (e: MouseEvent) => {
isDragging = false;
const style = window.getComputedStyle(dragElement);
dragPosition = {
startX: e.clientX,
startY: e.clientY,
startLeft: parseInt(style.left, 10) || 0,
startTop: parseInt(style.top, 10) || 0,
};
// 添加移动和松开事件
document.addEventListener('mousemove', move);
document.addEventListener('mouseup', stopDrag);
};
// 开始拖动 - 触摸事件
const startTouchDrag = (e: TouchEvent) => {
isDragging = false;
if (e.touches[0]) {
const style = window.getComputedStyle(dragElement);
dragPosition = {
startX: e.touches[0].clientX,
startY: e.touches[0].clientY,
startLeft: parseInt(style.left, 10) || 0,
startTop: parseInt(style.top, 10) || 0,
};
document.addEventListener('touchmove', move, { passive: false });
document.addEventListener('touchend', stopDrag);
}
};
// 添加事件监听
dragElement.addEventListener('mousedown', startMouseDrag);
dragElement.addEventListener('touchstart', startTouchDrag, { passive: false });
}
export default {};