前言
根据要求自制一款可拖动可最大化的弹窗组件效果如下:
放大效果如下:
废话不说。
- 首先获得当前页面的宽、高和初始窗口坐标,并水平垂直居中:
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});
}
}
好了 现在放大缩小也已经实现,大功告成,时间紧迫、代码简陋,莫要见笑!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。