react宽度可拖拽组件

了解拖拽之前先了解两个api

element.setCaptureelement.releaseCapture

setCapture: 在处理一个 mousedown 事件过程中调用这个方法来把全部的鼠标事件重新定向到这个元素,直到鼠标按钮被释放或者 document.releaseCapture() 被调用。
releaseCapture: 如果该 document 中的一个元素之上当前启用了鼠标捕获,则释放鼠标捕获

核心逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import React, { Component } from 'react';
import './index.scss';
import {Card,Icon,Input, Layout } from 'antd';
import TreeOrganize from './treeOrganize';
const { Sider, Content } = Layout;
let dragBtn, dragDom, dragCollDom;

export default class SelectDept extends Component {

componentDidMount() {
this.setSiderWidth();
}

// 设置侧边栏宽度
setSiderWidth = () => {
dragBtn = document.getElementById('drag-tip');
dragDom = document.getElementById('drag-area');
dragCollDom = document.getElementById('collapse_sider');
var siderWidth = Number(window.localStorage.getItem(this.props.SiderWidthDivide));
if (siderWidth == 0) {
this.setMaxValue(256);
} else {
if (siderWidth < 256) {
this.setMinValue(32);
} else {
this.setMaxValue(siderWidth);
}
};
}

isIE = () => navigator.userAgent.toLowerCase().indexOf('trident') > -1 ? true : false;

MouseDown = (e) => {
// 鼠标的X轴坐标
let clientX = e.clientX;
// 拖动块距离屏幕左侧的偏移量
let offsetLeft = dragBtn.offsetLeft;

// 鼠标移动
document.onmousemove = (e) => {
let curDist = offsetLeft + (e.clientX - clientX), // 拖动块的移动距离
maxDist = 700; // 拖动块的最大移动距离
// 边界值处理
if (curDist < 243) {
// 设置值(保证拖动块一直在拖动盒子的相对位置)
curDist < 32 && (curDist = 32);
this.setMinValue(curDist);
return false
}
curDist > maxDist && (curDist = maxDist);
this.setMaxValue(curDist);
return false;
};
// 鼠标松开
document.onmouseup = (e) => {
let curDist = offsetLeft + (e.clientX - clientX); // 拖动块的移动距离
if (curDist < 243) {
this.setMinValue(32);
}
document.onmousemove = null;
document.onmouseup = null;
// 释放鼠标
dragBtn.releaseCapture && dragBtn.releaseCapture();
};
// 捕获鼠标
dragBtn.setCapture && dragBtn.setCapture();
return false;
};

setMinValue = (curDist) => {
window.localStorage.setItem(this.props.SiderWidthDivide, '32');
if (this.isIE()) {
dragBtn.style.cssText = `left:${curDist}px;`;
dragCollDom.style.cssText = `flex:0 0 ${curDist}px;width:${curDist}px`;
dragDom.style.cssText = 'flex:0 0 0px;width:0px';
} else {
dragBtn.style.left = dragCollDom.style.width = curDist + 'px';
dragCollDom.style.flex = `0 0 ${curDist}px`;
dragDom.style.flex = '0 0 0px';
dragDom.style.width = '0px';
}
}

setMaxValue = (curDist) => {
window.localStorage.setItem(this.props.SiderWidthDivide, curDist);
// 设置值(保证拖动块一直在拖动盒子的相对位置)
if (this.isIE()) {
dragBtn.style.cssText = `left:${curDist}px;`;
dragDom.style.cssText = `flex:0 0 ${curDist}px;width:${curDist}px`;
dragCollDom.style.cssText = 'flex:0 0 0px;width:0px';
} else {
dragBtn.style.left = dragDom.style.width = curDist + 'px';
dragDom.style.flex = `0 0 ${curDist}px`;
dragCollDom.style.flex = '0 0 0px';
dragCollDom.style.width = '0px';
}
}

render() {
const { nodeClick, children, urlMatch,moreAction } = this.props;
return (
<Layout id="drag-content" >
<div id="collapse_sider" style={{ width: 0 }} >
<div id="collapse_sider_box">
<div className="base">组<br />织<br />架<br />构</div>
<Icon className="collapse_icon"
type="iconfont iconzhankai2"
onClick={() => this.setMaxValue(256)}
/>
</div>
</div>
<Sider id="drag-area" className="sider" >
<div className="whiteBox">
<TreeOrganize
type="sync"
urlMatch={urlMatch}
onTreeNodeClick={nodeClick}
setMinValue={this.setMinValue}
moreAction={moreAction}
/>
</div>
</Sider>
<div id="drag-tip" onMouseDown={this.MouseDown}>
<Icon className="drag_icon" type="iconfont icontuozhuai" />
</div>
<Layout style={{ paddingLeft: 24, overflowY: 'auto' }}>
<Content>
<Card bordered={false}>
{children}
</Card>
</Content>
</Layout>
</Layout>
);
}
}

样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@import "src/scss/variables";
#drag-content {
position: relative;
height: calc(100vh - 180px);
background: none;
.ant-layout {
background: none;
}

/*鼠标移入显示可拖动样式*/
#drag-tip {
top: 0;
width: 24px;
left: 256px;
height: 100%;
position: absolute;
background-color: transparent;
z-index: 1000;
transition: all 0s;
.drag_icon {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%);
font-size: 13px;
color: rgba(216, 216, 216, 1);
}
&:hover {
cursor: col-resize;
}
}

.sider {
box-shadow: none;
max-width: initial !important;
min-width: initial !important;
transition: all 0s;
background: rgba(238, 240, 243, 1);
.ant-layout-sider-children {
overflow: hidden;
}
}
#collapse_sider {
background: rgba(238, 240, 243, 1);
#collapse_sider_box {
position: relative;
height: 100%;
overflow: hidden;
}
.base {
position: absolute;
width: 100%;
top: 50%;
transform: translateY(-50%);
text-align: center;
}
.collapse_icon {
position: absolute;
width: 100%;
bottom: 10px;
text-align: center;
font-size: 12px;
color: #577ac7;
cursor: pointer;
}
}
.whiteBox {
width: 100%;
height: 100%;
padding: 0px 8px;
background-color: #eef0f3;
transition: width 0.3s;
overflow: hidden;
}
}