react拖拽实现网页
实现React拖拽功能的方法
使用react-dnd库实现拖拽功能
安装依赖:npm install react-dnd react-dnd-html5-backend
创建可拖拽组件时用useDrag hook,接收端用useDrop hook
需要包裹DndProvider并指定backend为HTML5Backend
import { useDrag, useDrop, DndProvider } from 'react-dnd'
import { HTML5Backend } from 'react-dnd-html5-backend'
function DraggableItem({ item }) {
const [{ isDragging }, drag] = useDrag(() => ({
type: 'ITEM',
item: { id: item.id },
collect: (monitor) => ({
isDragging: !!monitor.isDragging()
})
}))
return (
<div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
{item.content}
</div>
)
}
使用react-beautiful-dnd实现列表排序
安装:npm install react-beautiful-dnd
需要包裹DragDropContext组件Droppable定义放置区域,Draggable定义可拖拽项
通过onDragEnd回调处理排序逻辑
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
function SortableList({ items, onReorder }) {
const handleDragEnd = (result) => {
if (!result.destination) return
onReorder(result.source.index, result.destination.index)
}
return (
<DragDropContext onDragEnd={handleDragEnd}>
<Droppable droppableId="list">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
)
}
原生HTML5拖拽API实现
通过draggable属性标记可拖拽元素
监听dragstart、dragover和drop事件
需要阻止dragover事件的默认行为以允许放置
function NativeDrag() {
const handleDragStart = (e, id) => {
e.dataTransfer.setData('text/plain', id)
}
const handleDrop = (e) => {
e.preventDefault()
const id = e.dataTransfer.getData('text/plain')
// 处理放置逻辑
}
return (
<div
onDragOver={(e) => e.preventDefault()}
onDrop={handleDrop}
>
<div
draggable
onDragStart={(e) => handleDragStart(e, 'item1')}
>
可拖拽元素
</div>
</div>
)
}
拖拽性能优化建议
对于大量可拖拽项,使用虚拟滚动技术
避免在拖拽过程中频繁重渲染
考虑使用CSS transform代替top/left定位
对于复杂场景,使用Web Workers处理计算逻辑
跨框架拖拽解决方案
使用interact.js或draggable.js这类独立库
这些库不依赖特定框架,可与React配合使用
提供更精细的控制如限制移动范围、吸附网格等
import interact from 'interactjs'
function setupDrag(element) {
interact(element).draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
autoScroll: true
})
}






