鍍金池/ 問答/HTML/ 想問一下關于react實現(xiàn)面板拖曳的功能

想問一下關于react實現(xiàn)面板拖曳的功能

想問一個最基本的react實現(xiàn)拖曳面板的實現(xiàn)~
有一個add的button,鼠標點擊之后會彈出新面板,這個面板是通過絕對定位每次都定位在同一位置上的,想實現(xiàn)鼠標點擊這個面板之后的拖曳效果,
我的實現(xiàn)思路大概就是監(jiān)聽onmousedown,onmousemove和onmouseup,然后用一個flag,先點擊,獲取到點擊時的鼠標的坐標,將flag設為true,然后在mousemove的時候將每一次的位置給styleObj,最后mouseup的時候將flag設為false,

實現(xiàn)拖曳的效果貌似也不太對。。不太平滑,而且有時候方向是反的,可是我計算這個styleObj的left和top屬性值應該沒錯(move的clientX-點擊時得到的clientX+原始的left值)。

var index=0;
class Panel extends React.Component{
  constructor (props){
    super(props);
    this.state={
      styleObj:{
        top: 100,
        left:100
      },
      mouseXY:{
        //這個獲取的是每一次點擊panel時的鼠標的坐標
        x: 0,
        y: 0
      },
      isTouch:false
    };
   this.handleMouseDown = this.handleMouseDown.bind(this);
   this.handleMouseMove = this.handleMouseMove.bind(this);
   this.handleMouseUp = this.handleMouseUp
  }
  handleMouseDown(e){
    //獲取當前鼠標按下的位置,并把它放到stat里面去,并且要設置一個flag,使得只有觸發(fā)了點擊,才會 
    console.log(e.clientX);
    this.setState(
      {
      isTouch:!this.state.isTouch,
      mouseXY:{
        x:e.clientX,
        y:e.clientY
      }
      },function(){
        //callback,只有在上面改完才執(zhí)行
        this.printInfo();
      }
    );
  }
  printInfo(){
    console.log(this.state.mouseXY.x); //輸出此時的mouseXY的x
    console.log(this.state.isTouch); //輸出true
  }
  handleMouseMove(e){
    //先判斷是否已點擊,然后再需要讓這個panel的x,y隨滑動的位置發(fā)生相應的改變
    if(this.state.isTouch){
      this.setState({
      styleObj:{
         left:this.state.styleObj.left+e.clientX-this.state.mouseXY.x,
         top:this.state.styleObj.top+e.clientY-this.state.mouseXY.y,
      }
     })
    }
 }
  handleMouseUp(e){
    this.setState({
      isTouch:!this.state.isTouch
    })
  }
  render(){
    return (
    <div className="box" style={this.state.styleObj} onMouseDown={this.handleMouseDown} onMouseMove={this.handleMouseMove} onMouseUp={this.handleMouseUp}></div>
    )
  }
}
class App extends React.Component{
 constructor(props){
   super(props);
   this.state={listitem:[]};
   this.handleClick = this.handleClick.bind(this);
 }
  handleClick() {
    index++;
    this.setState({
      listitem :this.state.listitem.concat(<Panel key={index}>{index}</Panel>)
    });
 }
 render(){
  return (
   <div>
   <button onClick={this.handleClick}>
       Add
   </button>
   <div>
     {this.state.listitem}   
   </div>   
  </div>
 )
 }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
);

在第一條評論下面的是我修改之后不會有bug的,想問下這兩者的區(qū)別是什么~因為貌似給left和top的數(shù)值都是一樣的啊

回答
編輯回答
練命

如果是用在正式項目的話,螞蟻金服出的動畫解決方案了解一下,點擊傳送

2018年7月9日 19:23
編輯回答
別逞強
var index=0;
class Panel extends React.Component{
  constructor (props){
    super(props);
    this.state={
      styleObj:{
        top: 100,
        left:100
      },
      mouseXY:{
        //這個獲取的是每一次點擊panel時的鼠標在panel內的相對距離
        disX: 0,
        disY: 0
      },
      isTouch:false
    };
   this.handleMouseDown = this.handleMouseDown.bind(this);
   this.handleMouseMove = this.handleMouseMove.bind(this);
   this.handleMouseUp = this.handleMouseUp.bind(this);
  }
  handleMouseDown(e){
    //獲取當前鼠標按下的位置,并把它放到stat里面去,并且要設置一個flag,使得只有觸發(fā)了點擊,才會 
    console.log(e.clientX);
    this.setState(
      {
      isTouch:!this.state.isTouch,
      mouseXY:{
        disX:e.clientX-this.state.styleObj.left,
        disY:e.clientY-this.state.styleObj.top
      }
      },function(){
        //callback,只有在上面改完才執(zhí)行
        this.printInfo();
      }
    );
  }
  printInfo(){
    console.log(this.state.mouseXY.x); //輸出此時的mouseXY的x
    console.log(this.state.isTouch); //輸出true
  }
  handleMouseMove(e){
    //先判斷是否已點擊,然后再需要讓這個panel的x,y隨滑動的位置發(fā)生相應的改變
    const prevL=this.state.styleObj.left;
    const prevT=this.state.styleObj.top;
    // console.log('之前的'+prevL);
    // console.log(e.clientX+' '+this.state.mouseXY.x);
    if(this.state.isTouch){
      this.setState({
      styleObj:{
         left:e.clientX-this.state.mouseXY.disX,
         top:e.clientY-this.state.mouseXY.disY,
      }
     })
    }
 }
  handleMouseUp(e){
    this.setState({
      isTouch:!this.state.isTouch
    })
  }
  render(){
    return (
    <div className="box" style={this.state.styleObj} onMouseDown={this.handleMouseDown} onMouseMove={this.handleMouseMove} onMouseUp={this.handleMouseUp}></div>
    )
  }
}
class App extends React.Component{
 constructor(props){
   super(props);
   this.state={listitem:[]};
   this.handleClick = this.handleClick.bind(this);
 }
  handleClick() {
    index++;
    this.setState({
      listitem :this.state.listitem.concat(<Panel key={index}>{index}</Panel>)
    });
 }
 render(){
  return (
   <div>
   <button onClick={this.handleClick}>
       Add
   </button>
   <div>
     {this.state.listitem}   
   </div>   
  </div>
 )
 }
}
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
2017年4月4日 03:47