基于Ant Design的Modal组件来实现一个可拖拽的React模态框
写这篇文章的原因是因为在项目中用到了Antd Design的React组件,当有业务需求需要用到模态框的时候遇到了一些小问题,Antd的模态框Modal组件时不能拖拽的,一般情况下不可拖拽也没什么大的问题,但是遇到了客户提的需求,因此就想着在Modal组件原有的基础上进行扩展,封装一个可拖拽的模态框,当然我使用的这种方式不一定是最好的,所以仅仅是用于参考。
可以使用npm或yarn安装,可以直接使用下面的那段代码
npm install dragm
//OR
yarn add dragm
这是我安装之后直接复制了它的代码,你可以直接复制下面这段代码然后引入到自己项目中,而不需要在额外的安装
//DragM.js
import React from "react";
import PropTypes from "prop-types";
export default class DragM extends Reactponent {
static propTypes={
children: PropTypes.element.isRequired
};
static defaultProps={
//默认是移动children dom,覆盖该方法,可以把tranform行为同步给外部
updateTransform: (transformStr, tx, ty, tdom)=> {
tdom.style.transform=transformStr;
}
};
position={
startX: 0,
startY: 0,
dx: 0,
dy: 0,
tx: 0,
ty: 0
};
start=event=> {
if (event.button !==0) {
//只允许左键,右键问题在于不选择conextmenu就不会触发mouseup事件
return;
}
document.addEventListener("mousemove", this.docMove);
this.position.startX=event.pageX - this.position.dx;
this.position.startY=event.pageY - this.position.dy;
};
docMove=event=> {
const tx=event.pageX - this.position.startX;
const ty=event.pageY - this.position.startY;
const transformStr=`translate(${tx}px,${ty}px)`;
thisps.updateTransform(transformStr, tx, ty, this.tdom);
this.position.dx=tx;
this.position.dy=ty;
};
docMouseUp=event=> {
document.removeEventListener("mousemove", this.docMove);
};
componentDidMount() {
this.tdom.addEventListener("mousedown", this.start);
//用document移除对mousemove事件的监听
document.addEventListener("mouseup", this.docMouseUp);
}
componentWillUnmount() {
this.tdom.removeEventListener("mousedown", this.start);
document.removeEventListener("mouseup", this.docMouseUp);
document.removeEventListener("mousemove", this.docMove);
}
render() {
const { children }=thisps;
const newStyle={ ...childrenps.style, cursor: "move", userSelect: "none" };
return React.cloneElement(React.Children.only(children), {
ref: tdom=> {
return (this.tdom=tdom);
},
style: newStyle
});
}
}
前提是你安装了Antd,同时记得修改DragM的路径
//MovableModal.js
import React, { Component } from "react";
import { Modal } from "antd";
import DragM from "./DragM";
class MovableModal extends Component {
render() {
const updateTransform=transformStr=> {
this.modalDom=document.getElementsByClassName("ant-modal-content")[0];
this.modalDom.style.transform=transformStr;
};
const { children, title, ...other }=thisps;
const mytitle=(
);
return (
{thisps.children}
);
}
}
export default MovableModal;
使用方式和Modal组件使用方式一样,没有增加则外的属性
<MovableModal
visible={visible}
title="你的标题"
onOk={this.handleOk}
onCancel={this.handleCancel}
footer={[
,
<Button
key="submit"
type="primary"
loading={loading}
onClick={this.handleOk}
>
提交
>
具体的相关事件需要自己处理,也就是控制模态框显隐等。
这个方法目前发现的不足的地方就是在打开移动,然会关闭再打开就会发现位置保持在移动后的外置,因此需要在关闭后自己手动处理相关的属性。暂未发现明显的bug。
本方法算是比较暴力的一个方法了,从结果来看基本满足客户需求,当然也有不足的地方,如果大家有更好的解决方案,欢迎到评论区留言。如果本文对你有帮助,请记得帮忙转发、点赞加关注哦!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)