react中原生js实现左右拖动和上下拖动
昨天晚上杭州的雨可真大啊
淌水回家路~漫~漫~~
jsx:
import React, { Component } from 'react';
import _ from 'underscore';
import styles from './index.css';
// 可调整宽高的Div
export default class ResizeDiv extends Component {
state = {
isHResize: false,
isVResize: false,
hNum: 100,
vNum: 500,
hNumLimit: 30,
vNumLimit: 30,
};
resizeOffsetInfo = {
clientTop: 0,
clientLeft: 0,
};
leftHeight = 0;
containerWidth = 0;
componentDidMount() {
this.initResizeInfo();
const throttled = _.throttle(() => {
this.initResizeInfo();
}, 200);
window.onresize = throttled;
}
componentWillUnmount() {
window.onresize = null;
}
/**
* 初始化resize信息
*/
initResizeInfo = () => {
const hEle = document.getElementById('h_resize_container');
this.resizeOffsetInfo = this.getEleOffset(hEle);
this.leftHeight = hEle.offsetHeight;
this.containerWidth = document.getElementById('v_resize_container').offsetWidth;
};
/**
* 获取元素的偏移信息
*/
getEleOffset(ele) {
var clientTop = ele.offsetTop;
var clientLeft = ele.offsetLeft;
let current = ele.offsetParent;
while (current !== null) {
clientTop += current.offsetTop;
clientLeft += current.offsetLeft;
current = current.offsetParent;
}
return {
clientTop,
clientLeft,
height: ele.offsetHeight,
width: ele.offsetWidth,
};
}
/**
* 开始拖动水平调整块
*/
hResizeDown = () => {
this.setState({
isHResize: true,
});
};
/**
* 拖动水平调整块
*/
hResizeOver = e => {
const { isHResize, hNum, hNumLimit } = this.state;
if (isHResize && hNum >= hNumLimit && this.resizeOffsetInfo.height - hNum >= hNumLimit) {
let newValue = this.resizeOffsetInfo.clientTop + this.resizeOffsetInfo.height - e.clientY;
if (newValue < hNumLimit) {
newValue = hNumLimit;
}
if (newValue > this.resizeOffsetInfo.height - hNumLimit) {
newValue = this.resizeOffsetInfo.height - hNumLimit;
}
this.setState({
hNum: newValue,
});
}
};
/**
* 开始拖动垂直调整块
*/
vResizeDown = () => {
this.setState({
isVResize: true,
});
};
/**
* 拖动垂直调整块
*/
vResizeOver = e => {
const { isVResize, vNum, vNumLimit } = this.state;
if (isVResize && vNum >= vNumLimit && this.containerWidth - vNum >= vNumLimit) {
let newValue = e.clientX - this.resizeOffsetInfo.clientLeft;
if (newValue < vNumLimit) {
newValue = vNumLimit;
}
if (newValue > this.containerWidth - vNumLimit) {
newValue = this.containerWidth - vNumLimit;
}
this.setState({
vNum: newValue,
});
}
};
/**
* 只要鼠标松开或者离开区域,那么就停止resize
*/
stopResize = () => {
this.setState({
isHResize: false,
isVResize: false,
});
};
render() {
const hCursor = this.state.isHResize ? 'row-resize' : 'default';
const hColor = this.state.isHResize ? '#ddd' : '#fff';
const vCursor = this.state.isVResize ? 'col-resize' : 'default';
const vColor = this.state.isVResize ? '#ddd' : '#fff';
return (
<div
className={styles['container']}
onMouseUp={this.stopResize}
onMouseLeave={this.stopResize}
>
<div id="v_resize_container" className={styles['content']} onMouseMove={this.vResizeOver}>
<div
id="h_resize_container"
style={{ width: this.state.vNum, cursor: vCursor }}
className={styles['left']}
onMouseMove={this.hResizeOver}
>
<div
style={{ bottom: this.state.hNum, cursor: hCursor }}
className={styles['left-top']}
>
一一一一一一一
</div>
<div
style={{ bottom: this.state.hNum, backgroundColor: hColor }}
draggable={false}
onMouseDown={this.hResizeDown}
className={styles['h-resize']}
/>
<div
style={{ height: this.state.hNum + 4, cursor: hCursor }}
className={styles['left-bottom']}
>
二二二二二二二二二
</div>
</div>
<div
style={{ left: this.state.vNum, backgroundColor: vColor }}
draggable={false}
onMouseDown={this.vResizeDown}
className={styles['v-resize']}
/>
<div
style={{ marginLeft: this.state.vNum + 4, cursor: vCursor }}
className={styles['right']}
>
三三三三三三三三
</div>
</div>
</div>
);
}
}
css:
.container{
margin: 30px;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.content{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
min-height: 300px;
}
.left{
width: 500px;
height: 100%;
float: left;
position: relative;
}
.left-top{
position: absolute;
top: 0;
bottom: 104px;
width: 100%;
background-color: lightblue;
}
.h-resize{
height: 4px;
width: 100%;
background: #fff;
position: absolute;
bottom: 100px;
z-index: 1;
cursor: row-resize;
user-select: none;
}
.left-bottom{
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
background-color: lightgreen;
}
.v-resize{
height: 100%;
width: 4px;
position: absolute;
background: #fff;
left: 500px;
z-index: 2;
cursor: col-resize;
user-select: none;
}
.right{
margin-left: 504px;
background-color: lightsalmon;
height: 100%;
}