1

前言

根据要求自制一款可拖动可最大化的弹窗组件效果如下:
image.png
放大效果如下:
image.png
废话不说。

  • 首先获得当前页面的宽、高和初始窗口坐标,并水平垂直居中:
InitWindow=()=>{
        // 初始化窗口在当前页面的正中
        const {pageHeight,PageWidth}=this.state;
        let WindowX=document.body.clientWidth ;
        let WindowY=document.body.clientHeight;
        let pageX=WindowX/2-PageWidth/2;
        let pageY=WindowY/2-pageHeight/2;
        this.WindowWi=WindowX;//页面的宽、高
        this.WindowHi=WindowY;
        this.DefpageX=pageX;//初始坐标
        this.DefpageY=pageY;
        this.setState({pageX,pageY});
    }
  • 能够修改窗口状态有:宽、高和横纵坐标,所以要先预想。正文如下:
<div className="DragWindows" style={{height:pageHeight,width:PageWidth,left:pageX,top:pageY}}>
    <Row className="Header DragWindowsHeader" type="flex" justify="space-between" onMouseDown={this.onMouseDown}>
        <Col className="Title">标题</Col>
        <Col className="Edit">
            <Icon type="scan" className='Header_deformation' onClick={this.deformation}/>
            <Icon type="close" className='Header_close' onClick={this.props.onCancel}/>
        </Col>
    </Row>
    <div className="Content">
    {this.props.children}
    </div>
    <Row className="Footer" type="flex" justify="end">
        <Col>
            <Button onClick={this.props.onCancel}>取消</Button>
            <Button type="primary" onClick={this.props.onOk}>确定</Button>
        </Col>
    </Row>
</div>
  • 所有的动作都是由鼠标按下开始,并出发鼠标移动、鼠标按键up事件:
// 公共方法
    getPosition =(e)=> {
        const titleDom = e.target// 标题DOM元素titleDom
        const X = titleDom.getBoundingClientRect().left// titleDom的坐标(视窗)
        const Y = titleDom.getBoundingClientRect().top
        let mouseX = e.clientX ;// 鼠标点击的坐标(页面)
        let mouseY = e.clientY;
        const diffX = mouseX - X// 鼠标点击位置与modal的位置差
        const diffY = mouseY - Y
        return {X, Y, mouseX, mouseY, diffX, diffY};
    }
    // 鼠标移动
    onMouseDown =(e)=> {
        const position = this.getPosition(e)
        window.onmousemove = this.onMouseMove;
        window.onmouseup = this.onMouseUp
        this.setState({moving: true, diffX: position.diffX, diffY: position.diffY});
    }
     // 松开鼠标,设置modal状态为不可移动
    onMouseUp= (e)=> {
        const { moving } = this.state
        moving && this.setState({moving: false});
    }
    // 鼠标移动重新设置modal的位置
    onMouseMove =(e)=> {
        const {moving, diffX, diffY} = this.state
        if (moving) {
        const position = this.getPosition(e);// 获取鼠标位置数据
        const x = position.mouseX - diffX;// 计算modal应该随鼠标移动到的坐标
        const y = position.mouseY - diffY;
        const { clientWidth, clientHeight } = document.documentElement;// 窗口大小,结构限制,需要做调整,减去侧边栏宽度
        const modal = document.getElementsByClassName("DragWindowsHeader")[0]
        if (modal) {
            const maxHeight = clientHeight - modal.offsetHeight;// 计算modal坐标的最大值
            const maxWidth = clientWidth - modal.offsetWidth;
            const left = x > 0 ? (x < maxWidth ? x : maxWidth) : 0;// 判断得出modal的最终位置,不得超出浏览器可见窗口
            const top = y > 0 ? (y < maxHeight ? y : maxHeight) : 0
            this.setState({pageX: left, pageY: top})
        }
        }
    }
  • OK 拖拽功能已经实现。接下来我们实现放大缩小:
deformation=()=>{
    const {enlarge}=this;
    this.enlarge=!enlarge;
    if(this.enlarge){
        this.setState({pageHeight:this.WindowHi,PageWidth:this.WindowWi,pageX:0,pageY:0});
    }else{
        this.setState({pageHeight:this.DefPageHi,PageWidth:this.DefPageWi,pageX:this.DefpageX,pageY:this.DefpageY});
    }
}

好了 现在放大缩小也已经实现,大功告成,时间紧迫、代码简陋,莫要见笑!


九先生
48 声望3 粉丝

打工人,打工魂!