antd modal 拖动_Antd Modal 实现拖动功能

思路:

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事件时,显示drag-mask,并记录坐标(preX,preY);

4、mouseMove事件时,Modal的新位置=Modal的原位置+移动距离:

left2 = left1 + (pageX-preX);

top2 = top1 + (pageY-preY);

图示:由灰色位置移动到蓝色位置,箭头表示拖拽轨迹

5defcdb1d43566b0591abf37abb04ba7.png

5、mouseMove到窗口边缘时不能继续拖动,误差10px,也就是说拖拽时鼠标移动到靠近窗口边缘10px时就自动mouseUp;

代码:

import React, { Component } from 'react';

import ReactDom from'react-dom';

import { Modal, Empty } from'antd';

import'./dragable.less';

exportdefaultclass 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(

title='拖拽测试'visible={visible}

onCancel={this.hide}

style={style}

maskClosable={false}>

{

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;

}

注意:

现在Modal是可以拖动了,但是你可能会发现Modal中原本可以点击的子元素不能点了[○・`Д´・ ○] ~不要生气~这时给子元素设置定位position:relative,子元素就可以点击了。

因为.......同辈元素定位方式不同时,动态定位居上。即drag-target为absolute,它的兄弟元素是static,那么drag-target的层级就在兄弟元素们的上面。

同辈元素定位方式相同,且无z-index设置时,html靠后者层级居上。所以只要给drag-target的兄弟元素设置为relative,那么它们就不会被drag-target遮着了。

00f35475f63d306ec0ed7026ddcb6f05.png

ps:如果需要复用可以将其改写成高阶组件。

pps:因为暂时没有环境,所以上面的代码demo手敲完也没运行,如有问题欢迎指正讨论。

原文出处:https://www.cnblogs.com/JerryD/p/12161628.html


版权声明:本文为weixin_35006125原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。