与可调整大小的组件相关的问题

Tar*_*len 0 reactjs

我正在编写一个组件,如果单击其右边框并拖动它,则允许更改其子元素的宽度.

但是我有一些问题.首先,拖动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)

dam*_*nmr 6

这里有许多不同的问题......

首先,拖动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处理程序上的组件.

  • 我肯定会使用该插件并通过生命周期方法将其与React连接.这是最简单的方法,除非你真的想在你的UI中做一些不同/疯狂的事情. (2认同)