主页 > 开源代码  > 

实现可拖拽的AntDesignModal并保持下层HTML可操作性

实现可拖拽的AntDesignModal并保持下层HTML可操作性
前言

在开发复杂的前端界面时,我们常常需要一个可拖拽的弹窗(Modal),同时又希望用户能够在弹窗打开的情况下操作下层的内容。Ant Design 的 Modal 组件提供了强大的功能,但默认情况下,弹窗会覆盖整个页面,阻止用户与下层内容交互。本文将通过代码示例,展示如何实现一个可拖拽的 Modal,并确保弹窗不会影响下层 HTML 的操作。

效果图

视频演示

可拖拽antd Modal和保持下层 HTML 可操作性

技术栈

• React: 前端框架 • Ant Design: UI 组件库 • react-draggable: 可拖拽组件库

需求分析 可拖拽的 Modal: 用户可以通过拖拽 Modal 的标题栏来移动弹窗位置。下层内容可操作: 弹窗打开时,用户仍然可以操作下层的 HTML 元素。响应式拖拽限制: 弹窗的拖拽范围应限制在可视区域内。 实现思路使用 react-draggable 包装 Modal: 利用 react-draggable 提供的拖拽功能,将 Modal 包装为可拖拽组件。自定义 Modal 的遮罩层: 通过设置遮罩层的 pointerEvents 和 backgroundColor,使其完全透明且不阻止鼠标事件。动态计算拖拽边界: 根据窗口大小和 Modal 的尺寸,动态计算拖拽的边界,确保 Modal 不会超出可视区域。 代码实现 import { Button, Modal, Input } from 'antd'; import React, { useRef, useState } from 'react'; import type { DraggableData, DraggableEvent } from 'react-draggable'; import Draggable from 'react-draggable'; const text = `...`; // 省略的 Lorem Ipsum 文本 const App: React.FC = () => { const [open, setOpen] = useState(false); const [disabled, setDisabled] = useState(false); const [bounds, setBounds] = useState({ left: 0, top: 0, bottom: 0, right: 0 }); const draggleRef = useRef<HTMLDivElement>(null); const showModal = () => { setOpen(true); }; const handleOk = (e: React.MouseEvent<HTMLElement>) => { console.log(e); setOpen(false); }; const handleCancel = (e: React.MouseEvent<HTMLElement>) => { console.log(e); setOpen(false); }; const onStart = (_event: DraggableEvent, uiData: DraggableData) => { const { clientWidth, clientHeight } = window.document.documentElement; const targetRect = draggleRef.current?.getBoundingClientRect(); if (!targetRect) { return; } setBounds({ left: -targetRect.left + uiData.x, right: clientWidth - (targetRect.right - uiData.x), top: -targetRect.top + uiData.y, bottom: clientHeight - (targetRect.bottom - uiData.y), }); }; return ( <> <Button type="primary" onClick={showModal}>Open Draggable Modal</Button> <div> <Input placeholder="Input here" /> <p>{text}</p> <p>{text}</p> <p>{text}</p> <p>{text}</p> </div> <Modal title={ <div style={{ width: '100%', cursor: 'move', }} onMouseOver={() => { if (disabled) { setDisabled(false); } }} onMouseOut={() => { setDisabled(true); }} > Draggable Modal </div> } open={open} onOk={handleOk} onCancel={handleCancel} maskStyle={{ pointerEvents: 'none', // 禁用遮罩层的交互,允许下层内容被操作 backgroundColor: 'rgba(0, 0, 0, 0)', // 使遮罩层完全透明 }} modalRender={modal => ( <Draggable disabled={disabled} bounds={bounds} onStart={(event, uiData) => onStart(event, uiData)} > <div ref={draggleRef} style={{ position: 'relative', zIndex: 1000 }}> {modal} </div> </Draggable> )} bodyStyle={{ overflow: 'hidden' }} // 防止 Modal 内容滚动 style={{ pointerEvents: 'auto' }} // 确保 Modal 可以正常交互 getContainer={false} // 防止 Modal 被附加到默认的 body 中 wrapClassName="modal-no-mask" // 自定义样式类 > <p> Just don't learn physics at school and your life will be full of magic and miracles. </p> <br /> <p>Day before yesterday I saw a rabbit, and yesterday a deer, and today, you.</p> </Modal> <style> {` .modal-no-mask { pointer-events: none; /* 确保 Modal 不阻止鼠标事件 */ } .modal-no-mask .ant-modal-content { pointer-events: auto; /* 确保 Modal 内容可以交互 */ } `} </style> </> ); }; export default App; 关键点解析 react-draggable 的使用 • Draggable 组件通过 bounds 属性限制拖拽范围,确保 Modal 不会超出可视区域。 • onStart 回调函数用于动态计算拖拽边界。自定义遮罩层 • 通过设置 maskStyle 的 pointerEvents 为 none 和 backgroundColor 为透明,使遮罩层不会阻止鼠标事件,同时保持完全透明。Modal 的可交互性 • 设置 style={{ pointerEvents: ‘auto’ }} 确保 Modal 内容可以正常交互。 • 使用 getContainer={false} 防止 Modal 被附加到默认的 body 中,避免样式冲突。动态计算拖拽边界 • 在 onStart 回调中,根据窗口大小和 Modal 的尺寸动态计算拖拽边界,确保 Modal 的拖拽范围始终在可视区域内。 效果展示可拖拽的 Modal: 用户可以通过拖拽标题栏移动 Modal 的位置。下层内容可操作: 弹窗打开时,用户仍然可以操作下层的输入框和其他内容。响应式拖拽限制: Modal 的拖拽范围始终在可视区域内,不会超出屏幕边界。 总结

通过结合 react-draggable 和 Ant Design 的 Modal 组件,我们实现了一个可拖拽的弹窗,并确保弹窗不会影响下层 HTML 的操作。这种实现方式在复杂的前端界面中非常实用,例如在地图应用、图表展示或多任务操作场景中,用户可以在弹窗打开的情况下继续操作下层内容。 希望本文的实现思路和代码示例能为你的项目提供帮助!

标签:

实现可拖拽的AntDesignModal并保持下层HTML可操作性由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“实现可拖拽的AntDesignModal并保持下层HTML可操作性