一 目標:
實現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) => {
let H = document.body.clientHeight;
let 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;
}
}
onMouseDown = e => { e.preventDefault();
//記錄初始移動的鼠標位置 let startPosX = e.clientX; let startPosY = e.clientY; const { styleLeft, styleTop } = this.state;
//添加鼠標移動事件 document.body.onmousemove = e => { let left = e.clientX - startPosX + styleLeft; let 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={visible} onCancel={this.props.onCancel} style={style} footer={null} title={<div style={{ width: "100%", cursor: "move" }} onMouseDown={this.onMouseDown} >標題</div>} > <div>內容</div> </Modal > } } export default MoveModal