我正在使用ReactJS构建一个调整大小的组件。下面的代码:
class Cell extends React.Component {
handleMouseDown = event => {
this.props.onMouseDown(this.props.index, event);
};
render() {
let verticalGrip = ( <
div onMouseDown = {
this.handleMouseDown
}
className = "cell-vertical-grip" / >
);
return ( <
div className = "cell-container"
style = {
{
width: this.props.widths[this.props.index]
}
} >
<
div className = "cell-content"
style = {
{
border: "10px solid transparent"
}
} >
{
"WIDTH " + this.props.widths[this.props.index]
} <
/div> {
verticalGrip
} <
/div>
);
}
}
class Test extends React.Component {
state = {
widths: [100, 100, 100, 100],
baseWidths: [100, 100, 100, 100],
xBase: 0,
resizeIndex: null
};
handleMouseDown = (index, event) => {
console.log("MouseDown: index: " + index + ", pageX: " + event.pageX);
this.setState({
xBase: event.pageX,
resizing: true,
resizeIndex: index
});
};
handleMouseMove = event => {
if (this.state.resizing) {
let delta = this.state.xBase - event.pageX;
console.log("MouseMove " + delta);
let widths = this.state.widths.slice();
widths[this.state.resizeIndex] = this.state.baseWidths[this.state.resizeIndex] - delta;
this.setState({
widths: widths
});
}
};
handleMouseUp = event => {
console.log("MouseUp");
this.setState({
resizing: false,
resizeIndex: null
});
};
render() {
return ( <
div className = "test-container"
onMouseMove = {
this.handleMouseMove
}
onMouseUp = {
this.handleMouseUp
} >
<
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
0
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
1
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
2
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
3
}
/> <
/div>
);
}
}
// Render it
ReactDOM.render( <
Test / > ,
document.body
);
.test-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: row;
background-color: cyan;
}
.cell-container {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
background-color: grey;
border: 1px solid black;
overflow-y: hidden;
overflow-x: hidden;
}
.cell-content {
align-self: center;
flex-shrink: 1;
font-size: 12px;
overflow-y: hidden;
overflow-x: hidden;
background-color: white;
}
.cell-vertical-grip {
flex-shrink: 0;
margin-left: auto;
width: 3px;
min-width: 3px;
cursor: ew-resize;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
在verticalGrip
中,您可以抓住要调整大小的列。
很好,但是当我将任何列的大小调整为小于20px
的宽度时,我的问题就会出现。在这种情况下,我的蓝色握把(verticalGrip
项目)就消失了。因此,如果我将鼠标释放到该位置,则由于无法抓握(它消失了),因此无法再次扩展该列。
换句话说,如果他由于某种原因需要收缩色谱柱,由于没有抓地力,他不能再扩大它。
如何在所有可能的宽度上保持可见,使用户可以在任何情况下调整列的大小?
答案 0 :(得分:1)
一个想法是使元素在右侧保持粘性,并且由于要应用到元素的边框而导致溢出时,元素不会消失。
class Cell extends React.Component {
handleMouseDown = event => {
this.props.onMouseDown(this.props.index, event);
};
render() {
let verticalGrip = ( <
div onMouseDown = {
this.handleMouseDown
}
className = "cell-vertical-grip" / >
);
return ( <
div className = "cell-container"
style = {
{
width: this.props.widths[this.props.index]
}
} >
<
div className = "cell-content"
style = {
{
border: "10px solid transparent"
}
} >
{
"WIDTH " + this.props.widths[this.props.index]
} <
/div> {
verticalGrip
} <
/div>
);
}
}
class Test extends React.Component {
state = {
widths: [100, 100, 100, 100],
baseWidths: [100, 100, 100, 100],
xBase: 0,
resizeIndex: null
};
handleMouseDown = (index, event) => {
console.log("MouseDown: index: " + index + ", pageX: " + event.pageX);
this.setState({
xBase: event.pageX,
resizing: true,
resizeIndex: index
});
};
handleMouseMove = event => {
if (this.state.resizing) {
let delta = this.state.xBase - event.pageX;
console.log("MouseMove " + delta);
let widths = this.state.widths.slice();
widths[this.state.resizeIndex] = this.state.baseWidths[this.state.resizeIndex] - delta;
this.setState({
widths: widths
});
}
};
handleMouseUp = event => {
console.log("MouseUp");
this.setState({
resizing: false,
resizeIndex: null
});
};
render() {
return ( <
div className = "test-container"
onMouseMove = {
this.handleMouseMove
}
onMouseUp = {
this.handleMouseUp
} >
<
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
0
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
1
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
2
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
3
}
/> <
/div>
);
}
}
// Render it
ReactDOM.render( <
Test / > ,
document.body
);
.test-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: row;
background-color: cyan;
}
.cell-container {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
background-color: grey;
border: 1px solid black;
overflow-y: hidden;
overflow-x: hidden;
}
.cell-content {
align-self: center;
flex-shrink: 1;
font-size: 12px;
overflow-y: hidden;
overflow-x: hidden;
background-color: white;
}
.cell-vertical-grip {
flex-shrink: 0;
margin-left: auto;
width: 3px;
min-width: 3px;
cursor: ew-resize;
background-color: blue;
position:sticky;
right:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
或者您可以考虑另一个想法,而不是轮廓或框阴影之类的边框,这不会影响元素的宽度,并且您将获得相同的视觉输出:
class Cell extends React.Component {
handleMouseDown = event => {
this.props.onMouseDown(this.props.index, event);
};
render() {
let verticalGrip = ( <
div onMouseDown = {
this.handleMouseDown
}
className = "cell-vertical-grip" / >
);
return ( <
div className = "cell-container"
style = {
{
width: this.props.widths[this.props.index]
}
} >
<
div className = "cell-content"
style = {
{
outline: "10px solid #fff"
}
} >
{
"WIDTH " + this.props.widths[this.props.index]
} <
/div> {
verticalGrip
} <
/div>
);
}
}
class Test extends React.Component {
state = {
widths: [100, 100, 100, 100],
baseWidths: [100, 100, 100, 100],
xBase: 0,
resizeIndex: null
};
handleMouseDown = (index, event) => {
console.log("MouseDown: index: " + index + ", pageX: " + event.pageX);
this.setState({
xBase: event.pageX,
resizing: true,
resizeIndex: index
});
};
handleMouseMove = event => {
if (this.state.resizing) {
let delta = this.state.xBase - event.pageX;
console.log("MouseMove " + delta);
let widths = this.state.widths.slice();
widths[this.state.resizeIndex] = this.state.baseWidths[this.state.resizeIndex] - delta;
this.setState({
widths: widths
});
}
};
handleMouseUp = event => {
console.log("MouseUp");
this.setState({
resizing: false,
resizeIndex: null
});
};
render() {
return ( <
div className = "test-container"
onMouseMove = {
this.handleMouseMove
}
onMouseUp = {
this.handleMouseUp
} >
<
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
0
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
1
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
2
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
3
}
/> <
/div>
);
}
}
// Render it
ReactDOM.render( <
Test / > ,
document.body
);
.test-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: row;
background-color: cyan;
}
.cell-container {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
background-color: grey;
border: 1px solid black;
overflow-y: hidden;
overflow-x: hidden;
}
/*to push the element so we can see the outline*/
.cell-container:before {
content:"";
width:10px;
}
.cell-content {
align-self: center;
flex-shrink: 1;
font-size: 12px;
overflow-y: hidden;
overflow-x: hidden;
background-color: white;
}
.cell-vertical-grip {
flex-shrink: 0;
margin-left: auto;
width: 3px;
min-width: 3px;
cursor: ew-resize;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
答案 1 :(得分:0)
一个简单的解决方案可能是对CSS进行一些修改,以使您的抓手元素放置在absolute
上,并与父.cell-container
的右边缘和高度对齐并设置大小:
.cell-vertical-grip {
/* Add this */
position:absolute;
top:0;
height:100%;
right:0;
}
您还应该显式设置min-width
中的.cell-container
以匹配抓取器宽度,以便在容器完全折叠时仍可见:
.cell-container {
/* Add this */
min-width:3px;
position:relative;
}
我已使用以下代码段中的这些更改更新了您的代码:
class Cell extends React.Component {
handleMouseDown = event => {
this.props.onMouseDown(this.props.index, event);
};
render() {
let verticalGrip = ( <
div onMouseDown = {
this.handleMouseDown
}
className = "cell-vertical-grip" / >
);
return ( <
div className = "cell-container"
style = {
{
width: this.props.widths[this.props.index]
}
} >
<
div className = "cell-content"
style = {
{
border: "10px solid transparent"
}
} >
{
"WIDTH " + this.props.widths[this.props.index]
} <
/div> {
verticalGrip
} <
/div>
);
}
}
class Test extends React.Component {
state = {
widths: [100, 100, 100, 100],
baseWidths: [100, 100, 100, 100],
xBase: 0,
resizeIndex: null
};
handleMouseDown = (index, event) => {
console.log("MouseDown: index: " + index + ", pageX: " + event.pageX);
this.setState({
xBase: event.pageX,
resizing: true,
resizeIndex: index
});
};
handleMouseMove = event => {
if (this.state.resizing) {
let delta = this.state.xBase - event.pageX;
console.log("MouseMove " + delta);
let widths = this.state.widths.slice();
widths[this.state.resizeIndex] = this.state.baseWidths[this.state.resizeIndex] - delta;
this.setState({
widths: widths
});
}
};
handleMouseUp = event => {
console.log("MouseUp");
this.setState({
resizing: false,
resizeIndex: null
});
};
render() {
return ( <
div className = "test-container"
onMouseMove = {
this.handleMouseMove
}
onMouseUp = {
this.handleMouseUp
} >
<
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
0
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
1
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
2
}
/> <
Cell widths = {
this.state.widths
}
onMouseDown = {
this.handleMouseDown
}
index = {
3
}
/> <
/div>
);
}
}
// Render it
ReactDOM.render( <
Test / > ,
document.body
);
.test-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: row;
background-color: cyan;
}
.cell-container {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
background-color: grey;
border: 1px solid black;
overflow-y: hidden;
overflow-x: hidden;
/* Add this */
min-width:3px;
position:relative;
}
.cell-content {
align-self: center;
flex-shrink: 1;
font-size: 12px;
overflow-y: hidden;
overflow-x: hidden;
background-color: white;
}
.cell-vertical-grip {
flex-shrink: 0;
margin-left: auto;
width: 3px;
min-width: 3px;
cursor: ew-resize;
background-color: blue;
/* Add this */
position:absolute;
top:0;
height:100%;
right:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>