Antd Modal 可拖拽移动
一 目标:
实现antd Modal 弹窗或者其他弹窗的点击标题进行拖拽的效果
二 准备及思录:
1.使用antd Modal 组件,要想改变位置需要改变Modal style 的left 和top属性,其默认值分别为0,100
2.Modal 的标题可以使组件,给这个标题组件添加一个鼠标点击事件,记录下鼠标点击的位置;
当鼠标移动的时候计算鼠标当前的位置和初始的位置差就是弹窗相对于初始位置的移动距离,从而计算出弹窗的实际位置,
通过state 记录弹窗实际位置,从而更新弹窗的style,
3.计算鼠标的位置防止移除屏幕视图窗口
三 代码实现:
import { PureComponent } from 'react'
import { Modal } from 'antd'
class MoveModal extends PureComponent {
constructor(props) {
super(props) // Modal 的初始值
this.state = {
styleTop: 100,
styleLeft: 0
}
}
// 计算是否超出屏幕;超出后停止移动监听
inWindow = (left, top, startPosX, startPosY) => {
const H = document.body.clientHeight
const W = document.body.clientWidth
if ((left < 20 && startPosX > left) || (left > W - 20 && startPosX < left) || (top < 20 && startPosY > top) || (top > H - 20 && startPosY < top)) {
document.body.onmousemove = null
document.body.onmouseup = null
return false
}
return true
}
onMouseDown = (e) => {
e.preventDefault() // 记录初始移动的鼠标位置
const startPosX = e.clientX
const startPosY = e.clientY
const { styleLeft, styleTop } = this.state // 添加鼠标移动事件
document.body.onmousemove = (e) => {
const left = e.clientX - startPosX + styleLeft
const top = e.clientY - startPosY + styleTop
if (this.inWindow(e.clientX, e.clientY, startPosX, startPosY)) {
this.setState({
styleLeft: left,
styleTop: top
})
}
} // 鼠标放开时去掉移动事件
document.body.onmouseup = function() {
document.body.onmousemove = null
}
}
render() {
const { styleLeft, styleTop } = this.state
const style = { left: styleLeft, top: styleTop }
return (
<Modal
visible={this.props.visible}
onCancel={this.props.onCancel}
style={style}
footer={null}
title={
<div style={{ width: '100%', cursor: 'move' }} onMouseDown={this.onMouseDown}>
标题
</div>
}
>
{this.props.children}
</Modal>
)
}
}
export default MoveModal