我正在编写一个组件,如果单击其右边框并拖动它,则允许更改其子元素的宽度.
但是我有一些问题.首先,拖动div元素很尴尬,因为如果鼠标在拖动时向右移动另一个元素,拖动状态就会丢失并且会出错.
另外,当点在右边框的5个像素内时,我当前显示调整大小光标,在可调整大小的div内部工作正常.但是,如果您从右侧接近边框(鼠标位于其他div内),即使您在5像素范围内,也无法选择它.
另一个问题是当我拖动鼠标并调整div的大小时,鼠标会选择拖动它的文本.
最后,因为每次更改宽度时元素必须重新渲染,我注意到性能并不总是平滑的.
关于如何缓解这些问题的任何建议?
Resizable = React.createClass({
propTypes: {
id : React.PropTypes.string,
class : React.PropTypes.string,
width : React.PropTypes.number,
onResize : React.PropTypes.func,
onAction : React.PropTypes.func,
},
getInitialState: function() {
return {
showResizeCursor : false,
canResize : false,
};
},
getDefaultProps: function() {
return {
};
},
_handleMouseMove: function(event) {
var node = React.findDOMNode(this);
var offsets = node.getBoundingClientRect();
var divLeft = offsets.left;
var divRight = offsets.right;
var mouseX = event.clientX;
var maxWidth = this.props.maxWidth || this.props.width;
var minWidth = this.props.minWidth || this.props.width;
var newWidth = mouseX - divLeft + 200;
var isWithinBounds = newWidth <= maxWidth && newWidth >= minWidth;
if (this.state.canResize && isWithinBounds) {
this.props.onResize(newWidth);
}
var difference = Math.abs(divRight - mouseX);
if (difference < 4) {
return this.setState({ showResizeCursor: true });
}
if (this.state.showResizeCursor) {
this.setState({ showResizeCursor: false });
}
},
_handleMouseUp: function() {
this.setState({ canResize: false });
},
_handleMouseDown: function() {
if (this.state.showResizeCursor) {
this.setState({ canResize: true });
}
},
render: function() {
var style = {
width : this.state.width,
};
if (this.state.showResizeCursor) { style.cursor = 'col-resize'; }
return (
<div id={this.props.id}
style ={style}
className ={this.props.class}
onMouseDown ={this._handleMouseDown}
onMouseUp ={this._handleMouseUp}
onMouseMove ={this._handleMouseMove}
onMouseLeave={this._handleMouseUp}
>
{this.props.children}
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
用法示例:
render: function() {
...
return (
<Wrapper>
<Resizable
id = {'list-view'}
width = {this.state.listViewWidth}
maxWidth = {this.state.listViewMaxWidth}
minWidth = {this.state.listViewMinWidth}
onResize = {this._handleListViewResize}
>
{first_column_that_should_be_resizable}
</Resizable>
{second_column_not_resizeable}
Run Code Online (Sandbox Code Playgroud)
这里有许多不同的问题......
首先,拖动div元素很尴尬,因为如果鼠标在拖动时向右移动另一个元素,拖动状态就会丢失并且会出错.
当您开始编写第一个拖放相似的行为时,这是一个非常常见的问题.你不应该在同一个元素上监听mousedown,mousemove和mouseup事件,你应该只监听mousedown事件,并且在那个处理程序中开始监听另外两个但是在文档的主体上.这样,您就拥有了一个全局处理程序,并且您不会遇到鼠标越过其他元素的问题.
另外,当点在右边框的5个像素内时,我当前显示调整大小光标,在可调整大小的div内部工作正常.但是,如果您从右侧接近边框(鼠标位于其他div内),即使您在5像素范围内,也无法选择它.
我建议你只使用CSS.它是什么:)
另一个问题是当我拖动鼠标并调整div的大小时,鼠标会选择拖动它的文本.
是的,只是CSS.执行mousedown处理程序后,为元素添加一个特殊的CSS类,并在CSS中添加类似的东西.
.disable-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
Run Code Online (Sandbox Code Playgroud)
最后,因为每次更改宽度时元素必须重新渲染,我注意到性能并不总是平滑的.
我认为React不是你最好的选择.我只想使用jQuery和生命周期方法添加此行为componentDidMount.这样,您可以使用普通的jQuery(在每次鼠标移动时)调整div的大小,然后将最终状态(即最终大小)应用于mouseup处理程序上的组件.
| 归档时间: |
|
| 查看次数: |
1332 次 |
| 最近记录: |