思路:

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);

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

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

代码:

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 (
<div>
<Modal
title='拖拽测试'
visible={visible}
onCancel={this.hide}
style={style}
maskClosable={false}
>
<div className='drag-target' onMouseDown={this.handleMouseDown}></div>
<Empty description='啥也没有O_o' />
{
dragging &&
<div
                className='drag-mask'
                onMouseMove={this.handleMouseMove}
                onMouseUp={this.hanldeMouseUp}
               ></div>
}
</Modal>
</div>
)
}
}
.drag-mask{
position: fixed;
left:;
right:;
top:;
bottom:;
z-index:;
} .drag-target{
position: absolute;
left:;
right:;
top:;
bottom:;
cursor: move;
}

 注意:

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

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

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

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

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

让Antd Modal变成可拖动弹窗的更多相关文章

  1. Antd Modal 可拖拽移动

    一 目标: 实现antd Modal 弹窗或者其他弹窗的点击标题进行拖拽的效果 二 准备及思录: 1.使用antd  Modal 组件,要想改变位置需要改变Modal style 的left 和top ...

  2. react 可拖拽改变位置和大小的弹窗

    一 目标 最近,项目上需要一个可以弹出一个可以移动位置和改变大小的窗口,来显示一下对当前页面的一个辅助内容 二 思路 1.之前写过一个antd modal的可移动弹窗但是毕竟不如自己写的更定制化,比如 ...

  3. JS编写简单的弹窗插件(含有demo和源码)

    最近项目做完了 事情不是很多,今天正好也在调休,所以趁着这个时间研究了一下简易的JS弹窗功能,当然网上这块插件非常多,本人也没有仔细看网上的插件源码 只是凭着日常使用过的弹窗插件有这么多功能 来实现自 ...

  4. dialog参数、方法以及事件

    参数(options) DOM方式初始化dialog的,推荐使用集合属性data-options定义参数,如果使用data属性定义参数,注意转换成对应的名称. 名称 类型 默认值 描述 id stri ...

  5. BJUI 转

    B-JUI 前端框架B-JUI(Bootstrap for DWZ)是一个富客户端框架,基于DWZ-jUI富客户端框架修改. 本文是B-JUI中文使用手册,包括使用示例代码,感兴趣的同学参考下. 概览 ...

  6. Bootstrap模态弹出框

    前面的话 在 Bootstrap 框架中把模态弹出框统一称为 Modal.这种弹出框效果在大多数 Web 网站的交互中都可见.比如点击一个按钮弹出一个框,弹出的框可能是一段文件描述,也可能带有按钮操作 ...

  7. 关于React中状态保存的研究

    在使用react搭配react-router做应用的时候,你可能遇到这样的问题,当我从第一个页面过渡到第二个页面,然后返回之后,发现之前的页面的状态全部不见了,即回到了初始的状态. 这点在页面存在多个 ...

  8. 移动端 -webkit-user-select:text; ios10 bug 解决方案

    移动端一般body的css.会设置 作用就不解释了: body{ height:100%;min-height:100%; font-family: "微软雅黑",'Helveti ...

  9. angularJS的插件使用

    $uibModal&&$uibModalInstance $uibModal和$uibModalInstance是一款angularJS的弹窗控件,github地址 http://an ...

随机推荐

  1. 学linux内核与学linux操作系统有什么区别!?

    linux内核包括:进程管理,存储管理,IO管理,文件系统等功能.linux操作系统则是linux内核再加上像shell或图形界面和其他的实用软件,比内核庞大的多.建议先学shell命令和linux下 ...

  2. 传说中Python最难理解的点|看这完篇就够了(装饰器)

    https://mp.weixin.qq.com/s/B6pEZLrayqzJfMtLqiAfpQ 1.什么是装饰器 网上有人是这么评价装饰器的,我觉得写的很有趣,比喻的很形象 每个人都有的内裤主要是 ...

  3. [转]Netty实现原理浅析

    Netty是JBoss出品的高效的Java NIO开发框架,关于其使用,可参考我的另一篇文章netty使用初步.本文将主要分析Netty实现方面的东西,由于精力有限,本人并没有对其源码做了极细致的研 ...

  4. nano使用说明

    Main nano help text The nano editor is designed to emulate 仿真.模拟 the functionality and ease-of-use o ...

  5. codeforces1217-edu

    C The Number Of Good Substrings 我原来的基本思路也是这样,但是写的不够好 注意算前缀和的时候,字符串起始最好从1开始. #include<cstdio> # ...

  6. Laravel5.3使用学习笔记---中间件

    Laravel提供了中间件的使用.那什么是中间件呢,根据用法,我总结为,夹在“请求—>控制器—>响应—>end”中间运行的代码片段.本文将以官方英文文本为基础资料进行笔记记录. La ...

  7. vue-learning:34 - component - 内置组件 - 动态组件component 和 is属性

    component动态组件 / is属性 让多个组件使用同一个挂载点,并动态切换,这就是动态组件. 必要条件: 组件标签使用<component></component> 动态 ...

  8. CSS 兼容问题

    CSS常见兼容性问题总结 浏览器的兼容性问题通常是因为不同的浏览器对不同的代码有不同的解析造成页面显示不统一的情况,这里的浏览器通常指IE 6,7,8,9... Google Firefox Oper ...

  9. 关于redux和react-redux使用combinereducers之后的问题

    最近用react写项目的时候,开始复习之前学过的redux,记录一下一些坑,以防忘记 我现在的redux目录下有这么些东西 首先是index.js import { createStore } fro ...

  10. java.lang.NoSuchMethodException: com.hgkj.controler.action.UserAction.newsLoginAction()

    java.lang.NoSuchMethodException: com.hgkj.controler.action.UserAction.newsLoginAction() 不久前在学习struts ...