react中原生js实现左右拖动和上下拖动
昨天晚上杭州的雨可真大啊
淌水回家路~漫~漫~~
jsx:
import React, { Component } from 'react';import _ from 'underscore';import styles from './index.css';// 可调整宽高的Divexport 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 (<divclassName={styles['container']}onMouseUp={this.stopResize}onMouseLeave={this.stopResize}><div id="v_resize_container" className={styles['content']} onMouseMove={this.vResizeOver}><divid="h_resize_container"style={{ width: this.state.vNum, cursor: vCursor }}className={styles['left']}onMouseMove={this.hResizeOver}><divstyle={{ bottom: this.state.hNum, cursor: hCursor }}className={styles['left-top']}>一一一一一一一</div><divstyle={{ bottom: this.state.hNum, backgroundColor: hColor }}draggable={false}onMouseDown={this.hResizeDown}className={styles['h-resize']}/><divstyle={{ height: this.state.hNum + 4, cursor: hCursor }}className={styles['left-bottom']}>二二二二二二二二二</div></div><divstyle={{ left: this.state.vNum, backgroundColor: vColor }}draggable={false}onMouseDown={this.vResizeDown}className={styles['v-resize']}/><divstyle={{ 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%;}
