React:如何防止MUI可拖拽Dialog组件被拖出屏幕显示区域
你的边界校验逻辑已经正确计算了拖拽的合法范围,但是没有将计算得到的bounds参数传入Draggable组件,因此边界限制没有生效,另外你给容器绑定的ref类型有误,修正后的代码如下:
import * as React from 'react'; import Paper, { PaperProps } from '@mui/material/Paper'; import Draggable, { DraggableEvent, DraggableData } from 'react-draggable'; export const PaperComponent = (props: PaperProps) => { // 修正ref类型,绑定的是div元素不是input const widgetContainerRef = React.useRef<HTMLDivElement>(null); const [widgetState, setWidgetState] = React.useState({ visible: false, disabled: true, bounds: { left: 0, top: 0, bottom: 0, right: 0 }, }); const onStart = (event: DraggableEvent, uiData: DraggableData) => { const { clientWidth, clientHeight } = window.document.documentElement; const targetRect = widgetContainerRef.current?.getBoundingClientRect(); if (targetRect) { setWidgetState((prevState) => ({ ...prevState, bounds: { left: -targetRect.left + uiData.x, right: clientWidth - (targetRect.right - uiData.x), top: -targetRect.top + uiData.y, bottom: clientHeight - (targetRect.bottom - uiData.y), }, })); } }; return ( <Draggable handle="#draggable-dialog-title" cancel={'[class*="MuiDialogContent-root"]'} nodeRef={widgetContainerRef} onStart={(event, uiData) => onStart(event, uiData)} // 新增:传入计算好的边界参数,启用拖拽限制 bounds={widgetState.bounds} > <div ref={widgetContainerRef}> <Paper {...props} /> </div> </Draggable> ); };
额外注意事项:
- 要确保你使用的Dialog标题组件设置了
id="draggable-dialog-title",和Draggable的handle参数对应,拖拽功能才能正常触发 - 如果你的页面有滚动条,计算边界时可以替换
window.document.documentElement.clientWidth/clientHeight为window.innerWidth/window.innerHeight,适配窗口可视区域的实际大小
内容的提问来源于stack exchange,提问作者Ry10p
相关产品推荐
相关产品推荐

