如何在react-beautiful-dnd中限制Draggable组件不超出Droppable区域或指定div?
react-beautiful-dnd 拖拽边界约束可落地方案
- 拖拽生命周期回调实现实时视觉钳制
直接用库自带的onDragUpdate回调拿全流程的实时拖拽坐标,搭配自定义边界的尺寸信息做位置修正:- 提前把要约束的自定义div的DOM信息存下来,换算出x、y轴的可移动坐标范围——就是拿这个div的左上角、右下角的页面坐标当移动阈值,超出就不让走
- 拖拽过程中每次
onDragUpdate触发,都比对当前拖拽浮层的页面坐标和阈值,一旦超界,直接改拖拽浮层的transform值,把位移拉回边界里
这里要注意:react-beautiful-dnd的拖拽浮层是通过Portal挂到body下的,别直接去改Draggable本身的DOM节点,一定要找到那个Portal出来的拖拽浮层节点再改样式,不然会和库自己的位移逻辑打架,出现位置错乱。
- Droppable范围的交互逻辑层约束
如果只是要把拖拽的生效范围锁在Droppable区域里,不需要硬卡视觉位置,直接从逻辑层拦截就行,省得改样式和库冲突:- 在
onDragUpdate里判断当前拖拽的坐标是不是在目标Droppable的DOM矩形范围内 - 一旦发现坐标飘出Droppable范围,就给拖拽浮层加个半透明的禁用态样式,同时拦掉
onDragEnd的放置触发——不管视觉上是不是短暂飘出Droppable,都不会触发跨区排序、跨区放置,相当于从规则上把可生效的范围固定在Droppable内部。
- 在
- 位置计算层的深度适配方案
要是对拖拽流畅度要求很高,必须做到视觉上完全不越界,就直接在库的位置计算逻辑外面套一层拦截:- 把库内部计算拖拽偏移量的函数包一层,所有算出来的拖拽位移,先过一遍自己写的边界钳制函数做修正,再把修正后的值传给库的渲染逻辑
这种方式和库自带的自动滚动、边缘吸附逻辑是完全适配的,不会像手动改transform那样出现拖拽位置和容器滚动不同步的偏移问题。
- 把库内部计算拖拽偏移量的函数包一层,所有算出来的拖拽位移,先过一遍自己写的边界钳制函数做修正,再把修正后的值传给库的渲染逻辑
- 几个实际开发踩过的坑
- 别想着给自定义边界div加
overflow: hidden就把拖拽项框住,拖拽过程中节点已经挂到body下了,父容器的overflow约束根本不生效 - 算坐标阈值的时候一定要把当前页面的滚动偏移量算进去,不然一滚动,边界判断就全错位了
- 升级到react-beautiful-dnd 13.x以上版本的时候,注意Portal容器的类名改了,提前适配DOM选择逻辑,不然找半天找不到要改的拖拽节点
内容的提问来源于stack exchange,提问作者Rajat Verma
相关产品推荐
相关产品推荐

