思路:
1、首先需要两个DIV,一个是和视口一样大drag-mask,绑定mouseMove事件和mouseUp事件,另一个是和Modal一样大的drag-target,绑定mouseDown事件;
2、已知Modal的样式.ant-modal{position:relative;top:100px;left:0px;},通过更改top、left改变Modal位置;
3、mouseDown事件时,记录坐标
handleMoseDown=(evt)=>{ this.setSate({ dragging:true, preX:evt.pageX, preY:evt.pageY, }) }
4、mouseMove事件时,根据上一次的坐标和这一次的坐标计算Modal的新位置;
handleMouseMove=(evt)=>{ const {preX,preY,styleLeft,styleTop} = this.state; const left = styleLeft + (evt.pageX-preX); const top = styleTop + (evt.pageY-preY); this.setState({ preX:evt.pageX, preY:evt.pageY, styleLeft:left, styleTop:top, }) }
DEMO代码如下:
import React, { Component } from 'react'; import ReactDom from 'react-dom'; import { Modal, Empty } from 'antd'; import './dragable.less'; export default class DragableModal extends Component { constructor(props) { super(props); this.state = { visible:false, dragging: false, preX: 0, preY: 0, styleTop: 100, styleLeft:0, } this.windowH = document.body.clientHeight; this.windowW = document.body.clientWidth; } show = () => { this.setState({ visible: true, dragging: false, preX: 0, preY: 0, styleTop: 100, styleLeft:0, }) } hide = () => { this.setState({ visible:false }) } isOverWindow = (moveX, moveY) => { const er = 10; if (moveX < er) return true; if (moveX > (this.windowW - er)) return true; if (moveY < er) return true; if (moveY > (this.windowH - er)) return true; return false; } handleMoseDown=(evt)=>{ this.setSate({ dragging:true, preX:evt.pageX, preY:evt.pageY, }) } handleMouseMove = (evt) => { if (this.isOverWindow) { this.hanldeMouseUp(); return; } const {preX,preY,styleLeft,styleTop} = this.state; const left = styleLeft + (evt.pageX-preX); const top = styleTop + (evt.pageY-preY); this.setState({ preX:evt.pageX, preY:evt.pageY, styleLeft:left, styleTop:top, }) } hanldeMouseUp = () => { this.setState({dragging:false}) } render() { const { visible, dragging, styleLeft, styleTop } = this.state; const style = { left: styleLeft, top: styleTop } return (<Modal title='拖拽测试' visible={visible} onCancel={this.hide} style={style} maskClosable={false} >) } }this.handleMoseDown}>{ dragging && className='drag-mask'}
onMouseMove={this.handleMouseMove}
onMouseUp={this.hanldeMouseUp}
>
.drag-mask{ position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 1001; } .drag-target{ position: absolute; left: 0; right: 0; top: 0; bottom: 0; cursor: move; }
如果需要复用可以将其改写成高阶组件。
欢迎指出问题欢迎讨论