React结合antd制作可移动的Modal窗口

参考文章:https://segmentfault.com/a/1190000021880340

原文章用的是ts语法,没去了解过ts,这里直接改成了js写法,文件格式为.jsx,在其基础上完善了一下只能在页面视口范围内移动对话框
用法和普通的Modal一样
代码:

import React, { Component } from 'react';
import AntdModal from 'antd/lib/modal';
import 'antd/es/modal/style/index.css';

export default class AntDraggableModal extends Component {

    constructor(props) {
        super(props);
        this.simpleClass = "";
        this.header;
        this.contain;
        this.modalContent;
        this.mouseDownX = 0;
        this.mouseDownY = 0;
        this.deltaX = 0;
        this.deltaY = 0;
        this.translate_x = 0;
        this.translate_Y = 0;
        this.simpleClass = Math.random()
            .toString(36)
            .substring(2);
    }

    handleMove = (event) => {
        const deltaX = event.pageX - this.mouseDownX;
        const deltaY = event.pageY - this.mouseDownY;
        
        // 超过网页窗口范围,静止移动
        const {x, y, bottom, right} = this.modalContent.getBoundingClientRect();
        if((x <= 0 && deltaX < 0) || (y <= 0 && deltaY < 0) 
            || (right >= window.innerWidth && deltaX > 0) 
            || (bottom >= window.innerHeight && deltaY > 0)) return;
        
        this.deltaX = deltaX;
        this.deltaY = deltaY;

        this.modalContent.style.transform = `translate(${deltaX + this.translate_x}px, ${deltaY + this.translate_Y}px)`;
    };

    initialEvent = (open) => {
        const { title } = this.props;
        if (title && open) {
            setTimeout(() => {
                window.removeEventListener('mouseup', this.removeUp, false);

                this.contain = document.getElementsByClassName(this.simpleClass)[0];
                this.header = this.contain.getElementsByClassName('ant-modal-header')[0];
                this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0];

                this.header.style.cursor = 'all-scroll';
                this.header.style.padding = "4px 12px"
                this.header.onmousedown = (e) => {
                    this.mouseDownX = e.pageX;
                    this.mouseDownY = e.pageY;
                    document.body.onselectstart = () => false;
                    window.addEventListener('mousemove', this.handleMove, false);
                };
                window.addEventListener('mouseup', this.removeUp, false);
            }, 0);
        }
    };

    removeMove = () => {
        window.removeEventListener('mousemove', this.handleMove, false);
    };

    removeUp = (event) => {
        document.body.onselectstart = () => true;

        // 只有class为 ant-modal-title和ant-modal-header的元素触发removeUp,才进行记录平移后x, y坐标
        // 否者窗口可能会乱跳
        if(event.target.className == "ant-modal-title" || event.target.className == "ant-modal-header"){
            this.translate_x = this.translate_x + this.deltaX;
            this.translate_Y = this.translate_Y + this.deltaY;
            this.removeMove();
        }
    };

    componentDidMount() {
        const { open = false } = this.props;
        this.initialEvent(open);
    }

    componentWillUnmount() {
        this.removeMove();
        window.removeEventListener('mouseup', this.removeUp, false);
    }

    render() {
        const { children, wrapClassName, ...other } = this.props;
        const wrapModalClassName = wrapClassName ? `${wrapClassName} ${this.simpleClass}` : `${this.simpleClass}`;
        return (
            <AntdModal
                {...other}
                wrapClassName={wrapModalClassName}
            >{children}</AntdModal>
        );
    }
}

你可能感兴趣的:(前端,react.js,javascript,前端,前端框架)