react 拖拽排序---原生


  定義css, 兩個動畫
  

.drag-up {
  -webkit-animation: dragup ease 0.2s 1;
          animation: dragup ease 0.2s 1;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
  background-color: red;
}
.drag-down {
  -webkit-animation: dragdown ease 0.2s 1;
          animation: dragdown ease 0.2s 1;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
  background-color: green;
}
@-webkit-keyframes dragup {
  from {
    margin-top: 10px;
  }
  to {
    margin-top: 60px;
  }
}
@keyframes dragup {
  from {
    margin-top: 10px;
  }
  to {
    margin-top: 60px;
  }
}
@-webkit-keyframes dragdown {
  from {
    margin-bottom: 10px;
    margin-top: 60px;
  }
  to {
    margin-bottom: 60px;
    margin-top: 10px;
  }
}
@keyframes dragdown {
  from {
    margin-bottom: 10px;
    margin-top: 60px;
  }
  to {
    margin-bottom: 60px;
    margin-top: 10px;
  }
}

  一個是向上拖拽的動畫,一個是向下拖拽的樣式。

2.寫組件

class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {...props};
  }

  dragStart(e) {
    this.dragged = e.currentTarget;
  }
  dragEnd(e) {
    this.dragged.style.display = ‘block‘;

    e.target.classList.remove("drag-up");
    this.over.classList.remove("drag-up");

    e.target.classList.remove("drag-down");
    this.over.classList.remove("drag-down");
    

    var data = this.state.data;
    var from = Number(this.dragged.dataset.id);
    var to = Number(this.over.dataset.id);
    data.splice(to, 0, data.splice(from, 1)[0]);

    //set newIndex to judge direction of drag and drop
    data = data.map((doc, index)=> {
      doc.newIndex = index + 1;
      return doc;
    })

    this.setState({data: data});
  }

  dragOver(e) {
    e.preventDefault();

    this.dragged.style.display = "none";
    
    if (e.target.tagName !== "LI") {
      return;
    }

    //判斷當前拖拽target 和 經過的target 的 newIndex

    const dgIndex = JSON.parse(this.dragged.dataset.item).newIndex;
    const taIndex = JSON.parse(e.target.dataset.item).newIndex;
    const animateName = dgIndex > taIndex ? "drag-up" : "drag-down";


    if (this.over && e.target.dataset.item !== this.over.dataset.item) {
      this.over.classList.remove("drag-up", "drag-down");
    }

    if(!e.target.classList.contains(animateName)) {
      e.target.classList.add(animateName);
      this.over = e.target;
    }
  }
  render() {
    var listItems = this.state.data.map((item, i) => {
      return (
        <li 
          data-id={i}
          key={i}
          style={{height: "60px", border: "solid 1px #cccccc", margin: "10px 30%", borderRadius: "5px", backgroundColor: "green", color: "#ffffff"}}
          draggable=‘true‘
          onDragEnd={this.dragEnd.bind(this)}
          onDragStart={this.dragStart.bind(this)}
          data-item={JSON.stringify(item)}
        >{item.color}</li>
      )
     });
    return (
      <ul onDragOver={this.dragOver.bind(this)} className ="contain">
        {listItems}
      </ul>
    )
  }
}
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [
        {
          newIndex: 1,
          color: "red"
        },

        {
          newIndex: 2,
          color: "green"
        },

        {
          newIndex: 3,
          color: "blue"
        },

        {
          newIndex: 4,
          color: "yellow"
        },

        {
          newIndex: 5,
          color: "orange"
        },

        {
          newIndex: 6,
          color: "black"
        }
      ]
    }
  }
  render() {
    return (
      <div>
        <List data={this.state.data} /> 
      </div>
    )
  }
}



ReactDOM.render(
  <App />,
  document.getElementById(‘app‘),
);

 

解釋幾個三個方法
1.dragStart  把 target 賦值給了this

2.dragOver 把經過的 li 賦值給了 this, 並且在經過的li上,添加對應的class, 實現動畫效果。 這里比較了序號,判斷當前是向哪個方向拖拽。  並且比較了 經過li是否是同一個,不是的話,移除動畫效果。

3.dragEnd, 移除動畫效果, 並且比較數據,setState到最新的數據。

 

總結, 有點dom操作的思想。

demo地址: https://codepen.io/jhonyoung/pen/PeGpNL

原創。

 

react 拖拽排序

標簽:方向   lis   ext   classlist   地址   項目   event   end   mes   

原文地址:https://www.cnblogs.com/jhonyoung/p/8954512.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM