我使用 React 创建了一个触摸屏应用程序。我正在使用 dnd-kit 库来启用某些 div 的拖放功能。
我有一个日历,其中日期是列,行是类别。每个单元格都是一个可放置区域。不同长度的可拖动物品存储在 3 个独立的容器中。我可以将这些项目拖动到网格上并将它们放置在特定的单元格中。到目前为止一切正常。
现在我的问题:我的日历网格比屏幕宽,因此我将“overflow-y”设置为“auto”。现在我可以滚动并将我想要查看的部分置于焦点中。问题是,当我现在将 Draggable 元素之一拖动到日历网格时,Draggable 元素的计算位置会因滚动量而偏移。如果我向右滚动 50px,那么 Draggable 也距离我拖动的位置向右 50px。
有办法纠正这个问题吗?使用可放置单元格将可拖动元素拖动到日历上时要忽略滚动量吗?或者覆盖默认变换属性以考虑此偏移(仅当在日历上时)。
这是我的可拖动元素
` 从“@dnd-kit/core”导入{useDraggable}; 从“样式组件”导入样式;
const StyledDraggable = styled.div`
z-index: 2;
transform: ${props => props.transform};
position: ${props => props.position};
touch-action: manipulation;
`;
export function Draggable(props) {
const {attributes, listeners, setNodeRef, transform, isDragging} = useDraggable({
id: props.id,
data: {
type: 'draggable',
droppableId: props.id,
date: props.startDate
}
});
const tForm = transform ?
`translate3d(${transform.x}px, ${transform.y}px, 0)` : undefined;
const position = isDragging ? 'absolute' : null;
return (
<StyledDraggable ref={setNodeRef} transform={tForm} position={position} {...listeners} {...attributes}>
{props.children}
</StyledDraggable>
);
}
`
我已经尝试以某种方式计算悬停时日历 div 的滚动量,然后手动更改可拖动元素的转换样式属性,但没有成功: ` 函数handleDragMove(事件){ ...
let calendar = document.querySelector("#scrollContainer")
let draggableElement = document.getElementById(active.id).parentElement
let transformation = window.getComputedStyle(draggableOrder, null).transform
let xOffset = parseInt(transformation.split(",")[4])
let yOffset = parseInt(transformation.split(",")[5])
draggableElement.style.transform = "translate3d(" + (xOffset - calendar.scrollLeft) + "px, " + yOffset + "px, 0)"
}
`
所以我找到了一个解决方案。我确信有一个更优雅的内置解决方案,但我找到了一个解决方法:
我获取可拖动 div 的子元素,并手动覆盖左侧偏移量。为了计算偏移量,我使用日历 div、可拖动顺序 div(我的多个可拖动元素的原始 div 池)和事件本身(+ 固定偏移量)的位置
这是我计算位置的方法:
handleDragMove(event) {
...
const calendarRect = document.querySelector("#innerCalendar").getBoundingClientRect();
const draggableOrder = document.getElementById(active.id).parentElement.getBoundingClientRect();
const dropBoxRect = document.getElementById(active.data.current.container).getBoundingClientRect();
const x = event.delta.x + calendarRect.left - draggableOrder.left + dropBoxRect.left - 250;
document.getElementById(active.id).style.left = x + "px";
}
它可以工作(需要几分之一秒的时间来计算),但我仍然希望有一个更干净、最好是内置的解决方案。