react 拖拽排序

來源:互聯網
上載者:User

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

  react 拖拽排序。項目中用到了,記一筆。沒有用react-dnd, 沒有用react-beautiful-dnd, 因為需求簡單,所以就自己擼了一個。

  代碼很簡單

  定義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 拖拽排序

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.