import { banDrag, fps, getElementByRole, recoverDrag } from '@/lib/utils/dom'; import { BODY_CELL } from '@/lib/constants/dom-role'; import { Operator } from '@/lib/operator'; export const selecting = (operators: Record) => (rowId: string, columnId: string) => { const selectingAreaOperator = operators[Operator.selection]; const layoutOperator = operators[Operator.layout]; const bodyContainer = layoutOperator.getBodyContainerDom(); banDrag(); // 初始化 selectingAreaOperator.activeSelection(columnId, rowId); let continuousScrolling = false; const animationScroll = () => { if (!continuousScrolling) return; bodyContainer.scrollTop = bodyContainer.scrollTop + 1; requestAnimationFrame(animationScroll); }; const move = (event: MouseEvent) => fps(() => { const cell = getElementByRole(event.target as Element, BODY_CELL); if (cell) { const rowId = cell.getAttribute('row-id'); const columnId = cell.getAttribute('column-id'); selectingAreaOperator.updateSelection(columnId, rowId); } const bottomScroll = () => { // 鼠标 点 const mouseY = event.clientY; // 表格边界点 const containerY = bodyContainer.getBoundingClientRect().bottom; // 如果鼠标点在容器外一直滚动到头 if (mouseY > containerY) { continuousScrolling = true; animationScroll(); } else { // 停止持续滚动 continuousScrolling = false; // 移动时判断滑动 } // const { bottom: activeCellY, height } = cell.getBoundingClientRect(); }; bottomScroll(); }); const moveFinish = () => { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', moveFinish); selectingAreaOperator.finishSelection(); recoverDrag(); }; document.addEventListener('mousemove', move); document.addEventListener('mouseup', moveFinish); };