You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-beautiful-dnd:滚动容器内拖拽起始位置异常问题求助

解决react-beautiful-dnd滚动容器下拖拽起始位置偏移问题

问题根源

当容器设置overflow-y: auto成为滚动容器后,react-beautiful-dnd默认基于视口计算元素位置,未纳入容器的滚动偏移量(scrollTop),导致拖拽起始位置错误。

修复步骤及代码调整

  1. 修正Draggable的index参数
    你之前用MI.id作为index是错误的,react-beautiful-dnd要求index必须是元素在数组中的当前顺序索引,否则会导致排序逻辑和位置计算混乱。

  2. 补充dragHandleProps
    必须将provided.dragHandleProps传递给拖拽触发元素,确保拖拽行为的正确触发和位置计算。

  3. 指定滚动容器给Droppable
    通过getContainer配置让react-beautiful-dnd识别滚动容器,自动处理滚动偏移量。

调整后的完整代码:

import { useRef } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

// ... 其他业务代码

const draggableContainerRef = useRef(null);

// ... 组件内部渲染逻辑
<div className={`${styles.draggableContainer}`} ref={draggableContainerRef}>
    <DragDropContext onDragEnd={onDragEnd}>
        <Droppable 
            droppableId="menuItems"
            getContainer={() => draggableContainerRef.current}
        >
            {(provided) => (
                <div {...provided.droppableProps} ref={provided.innerRef} className={styles.menu_container}>
                    {menuItemArr.map((MI, index) => (
                        <Draggable key={MI.id} draggableId={MI.id.toString()} index={index} id={MI.id}>
                            {(provided) => (
                                <div 
                                    ref={provided.innerRef} 
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                    className={`${styles.popup_form_custom} ${styles.draggable}`}
                                >
                                    <div className={styles.popup_formbox}>
                                        <label className={styles.smaller_font}>Percentage</label>
                                        <input 
                                            type="text" 
                                            placeholder="%" 
                                            value={MI.percentage} 
                                            onChange={(selected) => handleMenuArr("percentage", selected.target.value, MI.id)}
                                        />
                                    </div>
                                </div>
                            )}
                        </Draggable>
                    ))}
                    {provided.placeholder}
                </div>
            )}
        </Droppable>
    </DragDropContext>
</div>

额外排查点

  • 检查滚动容器的CSS,确保没有设置transform属性(transform会改变坐标上下文,导致位置计算错误)。
  • 若容器使用fixed/absolute定位,确认getContainer返回的DOM节点正确。

内容的提问来源于stack exchange,提问作者sfhasfasf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:23:20