让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);
图示:由灰色位置移动到蓝色位置,箭头表示拖拽轨迹
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变成可拖动弹窗的更多相关文章
- Antd Modal 可拖拽移动
一 目标: 实现antd Modal 弹窗或者其他弹窗的点击标题进行拖拽的效果 二 准备及思录: 1.使用antd Modal 组件,要想改变位置需要改变Modal style 的left 和top ...
- react 可拖拽改变位置和大小的弹窗
一 目标 最近,项目上需要一个可以弹出一个可以移动位置和改变大小的窗口,来显示一下对当前页面的一个辅助内容 二 思路 1.之前写过一个antd modal的可移动弹窗但是毕竟不如自己写的更定制化,比如 ...
- JS编写简单的弹窗插件(含有demo和源码)
最近项目做完了 事情不是很多,今天正好也在调休,所以趁着这个时间研究了一下简易的JS弹窗功能,当然网上这块插件非常多,本人也没有仔细看网上的插件源码 只是凭着日常使用过的弹窗插件有这么多功能 来实现自 ...
- dialog参数、方法以及事件
参数(options) DOM方式初始化dialog的,推荐使用集合属性data-options定义参数,如果使用data属性定义参数,注意转换成对应的名称. 名称 类型 默认值 描述 id stri ...
- BJUI 转
B-JUI 前端框架B-JUI(Bootstrap for DWZ)是一个富客户端框架,基于DWZ-jUI富客户端框架修改. 本文是B-JUI中文使用手册,包括使用示例代码,感兴趣的同学参考下. 概览 ...
- Bootstrap模态弹出框
前面的话 在 Bootstrap 框架中把模态弹出框统一称为 Modal.这种弹出框效果在大多数 Web 网站的交互中都可见.比如点击一个按钮弹出一个框,弹出的框可能是一段文件描述,也可能带有按钮操作 ...
- 关于React中状态保存的研究
在使用react搭配react-router做应用的时候,你可能遇到这样的问题,当我从第一个页面过渡到第二个页面,然后返回之后,发现之前的页面的状态全部不见了,即回到了初始的状态. 这点在页面存在多个 ...
- 移动端 -webkit-user-select:text; ios10 bug 解决方案
移动端一般body的css.会设置 作用就不解释了: body{ height:100%;min-height:100%; font-family: "微软雅黑",'Helveti ...
- angularJS的插件使用
$uibModal&&$uibModalInstance $uibModal和$uibModalInstance是一款angularJS的弹窗控件,github地址 http://an ...
随机推荐
- 怎么清除火狐浏览器的cookie?
火狐浏览器清除Cookie方法/步骤 1.打开火狐浏览器.并在火狐浏览器工具栏找到并单击“工具”下的“选项”. 2.在打开的“火狐浏览器选项”程序窗口中,找到工具栏中的“隐私”并单击,在隐私选项下找到 ...
- Oracle/PLSQL存储过程详解
原文链接:https://blog.csdn.net/zezezuiaiya/article/details/79557621 Oracle/PLSQL存储过程详解 2018-03-14 17:31: ...
- LRJ-Example-06-16-Uva10129
#include <cstdio> #include <cstring> #include <vector> using namespace std; + ; // ...
- 使用提示(Hints)
对于表的访问,可以使用两种Hints. FULL 和 ROWID FULL hint 告诉ORACLE使用全表扫描的方式访问指定表. 例如: SELECT /*+ FULL(EMP) */ * FRO ...
- 【codeforces 520B】Two Buttons
[题目链接]:http://codeforces.com/contest/520/problem/B [题意] 给你一个数n; 对它进行乘2操作,或者是-1操作; 然后问你到达m需要的步骤数; [题解 ...
- UVA 3027 Corporative Network 带权并查集、
题意:一个企业要去收购一些公司把,使的每个企业之间互联,刚开始每个公司互相独立 给出n个公司,两种操作 E I:询问I到I它连接点最后一个公司的距离 I I J:将I公司指向J公司,也就是J公司是I公 ...
- 洛谷P3150 pb的游戏(1)题解 博弈论入门
题目链接:https://www.luogu.org/problem/P3150 这道题目是博弈论的入门题. 我们以 必胜态 和 必败态 来讲解这个问题. 首先,下面的图片演示了前8个数的必胜态和必败 ...
- vue-lazyload: 想弃坑,但没有找到合适的替代品
vue-lazyload,相信在vue项目中大家都有用到过它,同时也遇到过大大小小的坑.笔者也遇到过这样一个bug,在一个图片列表页面中,总有一定的概率图片的状态为load,导致图片一直加载中...这 ...
- The bind() Method
The bind() method was added in ESMAScript 5, but it is easy to simulate in ESMAScrpt 3. As its name ...
- Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...