首先实现拖拽必须定义定位为固定定位,我们在组件中定义一个盒子,设置为固定定位,并且设置top值以及left值,这两个由于是变化的因此我们需要定义state值从而拖过拖拽改变该值。
拖拽需要三个事件,鼠标按下事件 鼠标抬起事件 以及鼠标移动事件
在定义鼠标按下事件时(MouseDown)我们需要将它的x,y鼠标坐标改为我们的当前鼠标的坐标位置-元素位于我们页面的xy坐标位置,这样就可以获取我们鼠标在元素中的x,y坐标位置。
移动时需要定义移动鼠标方法(onMouseMove),定义它的位置为当前坐标位置-在页面的坐标位置,这样减去偏移量可以获取到我们移动到的位置。
最后鼠标抬起以后设置为不进行拖拽。
{children}
const [isDragging, setIsDragging] = useState(false);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [offset, setOffset] = useState({ x: 0, y: 0 });
const handleMouseDown = (event) => {
event.preventDefault();
setIsDragging(true);
setOffset({
x: event.clientX - position.x,
y: event.clientY - position.y,
});
};
const handleMouseMove = (event) => {
if (isDragging) {
setPosition({
x: event.clientX - offset.x,
y: event.clientY - offset.y,
});
}
};
const handleMouseUp = () => {
setIsDragging(false);
};
使用:
{item.text}
移动端实现方式:
思路一样,只是使用到的是移动端的拖拽方法
const DraggableComponent = ({ children }) => {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [isDragging, setIsDragging] = useState(false);
const [touchStartPos, setTouchStartPos] = useState({ x: 0, y: 0 });
const handleTouchStart = (event) => {
setIsDragging(true);
setTouchStartPos({
x: event.touches[0].clientX - position.x,
y: event.touches[0].clientY - position.y,
});
};
const handleTouchMove = (event) => {
if (!isDragging) return;
const touchX = event.touches[0].clientX - touchStartPos.x;
const touchY = event.touches[0].clientY - touchStartPos.y;
setPosition({ x: touchX, y: touchY });
};
const handleTouchEnd = () => {
setIsDragging(false);
};
return (
{children}
);
};
包裹住需要拖拽的盒子
{item.text}
const [listItems, setListItems] = useState([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
{ id: 4, text: 'Item 4' },
{ id: 5, text: 'Item 5' },
]);
const [draggedItem, setDraggedItem] = useState(null);
const handleDragStart = (event, index) => {
setDraggedItem(listItems[index]);
event.dataTransfer.effectAllowed = 'move';
// Needed for Firefox to enable dragging
event.dataTransfer.setData('text/plain', '');
};
const handleDragEnter = (index) => {
if (!draggedItem) return;
if (draggedItem.id === listItems[index].id) return;
const newList = [...listItems];
newList.splice(index, 0, newList.splice(listItems.indexOf(draggedItem), 1)[0]);
setListItems(newList);
};
const handleDragEnd = () => {
setDraggedItem(null);
};
div>
Draggable List
{listItems.map((item, index) => (
- handleDragStart(event, index)}
onDragEnter={() => handleDragEnter(index)}
onDragEnd={handleDragEnd}
>
{item.text}
))}