一、插件实现
1.dragm
链接:www.npmjs.com/package/dra…
下载量:898
安装插件:cnpm i dragm
代码实现:
1.封装组件
import React from 'react';
import DragM from 'dragm';
export default class ModalDrag extends React.Component {
updateTransform = transformStr => {
this.modalDom.style.transform = transformStr;
};
componentDidMount() {
this.modalDom = document.getElementsByClassName(
'ant-modal-wrap', // modal的class是ant-modal-wrap
)[0];
}
render() {
const { title } = this.props;
return (
<DragM updateTransform={this.updateTransform}>
<div>{title}</div>
</DragM>
);
}
}
2.Modal中引用组件
import React from 'react';
import { Modal } from 'antd';
import ModalDrag from '@/components/ModalDrag';
export default class Demo extends React.Component {
render(){
const title = <ModalDrag title="标题” />
return(
<Modal
title={title}
>
</Modal>
)
}
}
2.antd-draggable-modal
链接:www.npmjs.com/package/ant…
下载量:126
安装插件:cnpm i antd-draggable-modal
代码实现:
import React, { PureComponent } from 'react';
import { Button } from 'antd';
import AntdDraggableModal from 'antd-draggable-modal';
class Test extends PureComponent {
state = {
visible: false,
}
handleVisible = visible => {
this.setState({
visible,
});
}
handleOk = () => {
this.handleVisible(false);
}
handleCancel = () => {
this.handleVisible(false);
}
render() {
return (
<Button onClick={() => this.handleVisible(true)}>打开弹窗</Button>
{this.state.visible && (
<AntdDraggableModal
title="Basic Modal"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</AntdDraggableModal>
)}
);
}
}
export default Test;
\
二、封装组件
代码:
import type { MouseEvent } from 'react';
import { Component } from 'react';
import type { ModalProps } from 'antd/lib/modal';
import { Modal } from 'antd';
import 'antd/es/modal/style/index.css';
export default class AntDraggableModal extends Component<ModalProps> {
private simpleClass: string;
private header: any;
private contain: any;
private modalContent: any;
private mouseDownX: number = 0;
private mouseDownY: number = 0;
private deltaX: number = 0;
private deltaY: number = 0;
private sumX: number = 0;
private sumY: number = 0;
private offsetLeft: number = 0;
private offsetTop: number = 0;
constructor(props: ModalProps) {
super(props);
this.simpleClass = Math.random().toString(36).substring(2);
}
handleMove = (event: any) => {
const deltaX = event.pageX - this.mouseDownX;
const deltaY = event.pageY - this.mouseDownY;
this.deltaX = deltaX;
this.deltaY = deltaY;
let tranX = deltaX + this.sumX;
let tranY = deltaY + this.sumY;
// 左侧
if (tranX < -this.offsetLeft) {
tranX = -this.offsetLeft;
}
// 右侧
const offsetRight =
document.body.clientWidth -
this.modalContent.parentElement.offsetWidth -
this.offsetLeft;
if (tranX > offsetRight) {
tranX = offsetRight;
}
// 上侧
if (tranY < -this.offsetTop) {
tranY = -this.offsetTop;
}
// 下侧
const offsetBottom =
document.body.clientHeight -
this.modalContent.parentElement.offsetHeight -
this.offsetTop;
if (tranY > offsetBottom) {
tranY = offsetBottom;
}
this.modalContent.style.transform = `translate(${tranX}px, ${tranY}px)`;
};
initialEvent = (visible: boolean) => {
const { title } = this.props;
if (title && visible) {
setTimeout(() => {
window.removeEventListener('mouseup', this.removeUp, false);
this.contain = document.getElementsByClassName(this.simpleClass)[0];
this.header = this.contain.getElementsByClassName('ant-modal-header')[0];
this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0];
this.offsetLeft = this.modalContent.parentElement.offsetLeft;
this.offsetTop = this.modalContent.parentElement.offsetTop;
this.header.style.cursor = 'all-scroll';
this.header.onmousedown = (e: MouseEvent<HTMLDivElement>) => {
this.mouseDownX = e.pageX;
this.mouseDownY = e.pageY;
document.body.onselectstart = () => false;
window.addEventListener('mousemove', this.handleMove, false);
};
window.addEventListener('mouseup', this.removeUp, false);
}, 0);
}
};
removeMove = () => {
window.removeEventListener('mousemove', this.handleMove, false);
};
removeUp = () => {
// document.body.onselectstart = () => true;
this.sumX += this.deltaX;
this.sumY += this.deltaY;
this.deltaX = 0;
this.deltaY = 0;
if (this.sumX < -this.offsetLeft) {
this.sumX = -this.offsetLeft;
}
const offsetRight =
document.body.clientWidth -
this.modalContent.parentElement.offsetWidth -
this.offsetLeft;
if (this.sumX > offsetRight) {
this.sumX = offsetRight;
}
// 上侧
if (this.sumY < -this.offsetTop) {
this.sumY = -this.offsetTop;
}
// 下侧
const offsetBottom =
document.body.clientHeight -
this.modalContent.parentElement.offsetHeight -
this.offsetTop;
if (this.sumY > offsetBottom) {
this.sumY = offsetBottom;
}
this.removeMove();
};
componentDidMount() {
const { visible = false } = this.props;
this.initialEvent(visible);
}
componentWillReceiveProps(newProps: any) {
const { visible } = this.props;
if (newProps.visible && !visible) {
this.initialEvent(newProps.visible);
}
if (visible && !newProps.visible) {
this.removeMove();
window.removeEventListener('mouseup', this.removeUp, false);
}
}
componentWillUnmount() {
this.removeMove();
window.removeEventListener('mouseup', this.removeUp, false);
}
render() {
const { children, wrapClassName, ...other } = this.props;
const wrapModalClassName = wrapClassName
? `${wrapClassName} ${this.simpleClass}`
: `${this.simpleClass}`;
return (
<Modal {...other} wrapClassName={wrapModalClassName}>
{children}
</Modal>
);
}
}