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

 

posted @ 2020-07-07 09:38  少年工藤  阅读(4770)  评论(5编辑  收藏  举报