React 实现拖拽功能的示例代码

(编辑:jimmy 日期: 2024/11/19 浏览:2)

本文介绍了React 实现拖拽功能的示例代码,分享给大家,具体如下:

实现效果:

React 实现拖拽功能的示例代码

因为工作中会用到 JIRA 所以想实现一下相似的功能,顺便学习一下 H5 的拖拽。不支持拖拽改变顺序,感觉有点麻烦,而且没必要。感觉相关的博文好少的,大部分都是直接上代码,没有解释。

图片默认可以拖动,其他元素的拖动效果同图片。正常的 div 是不能被拖动的,鼠标点击选择后移动没有效果,需要加  draggable="true" 使得元素可以被拖动。

拖拽相关的几个事件,有被拖动元素的事件,也有拖动进入的容器元素的事件。 

被拖拽元素的事件:ondragstart,ondragend 

放置元素的事件:ondragenter、ondragover、ondragleave、ondrop 

顾名思义,不需要解释。

需要注意是  ondragover 的默认事件 Reset the current drag operation to "none". 所以想让一个元素可放置,需要重写 ondragover 

element.ondragover = event => { 
  event.preventDefault();
  // ...
}

当一个元素是可放置的,拖拽经过时鼠标会变成加号(cursor: copy;)

有一个对象  dataTransfer 可以用来存储拖拽数据。

dragEle.ondragstart = e => e.dataTransfer.setData('item', e.target.id);
拖拽开始时触发,把被拖拽元素的 id 存入  e.dataTransfer 

然后在 ondrop 的时候 可以获取到这个值 (ondragenter、ondragover、ondragleave 获取不到...)

putEle.ondrop = function(e) {
   let id = e.dataTransfer.getData('item');
   // ...
}
简单的应用:
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
  .wrapper {display: flex;border: 1px solid orangered;padding: 10px;}
  .col {border: 1px solid #808080;height: 500px;width: 200px;margin: 0 10px;padding: 10px;}
  .item {border: 1px solid #808080;margin: 5px 0;}
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="col1 col">
      <div class="item" id="item1" draggable="true">item1</div>
      <div class="item" id="item2" draggable="true">item2</div>
      <div class="item" id="item3" draggable="true">item3</div>
    </div>
    <div class="col2 col"></div>
    <div class="col3 col"></div>
    <div class="col4 col"></div>
  </div>
  <script>
    let cols = document.getElementsByClassName('col');
    for (let col of cols) {
      col.ondragenter = e => { 
        console.log('放置元素 ondragenter', '<' + e.dataTransfer.getData('item') + '>'); 
      }
      col.ondragover = e => {
        e.preventDefault();
        console.log('放置元素 ondragover', '<' + e.dataTransfer.getData('item') + '>');
      }
      col.ondragleave = e => { 
        console.log('放置元素 ondragleave', '<' + e.dataTransfer.getData('item') + '>'); 
      }
      col.ondrop = function(e) {
        console.log('放置元素 ondrop', '<' + e.dataTransfer.getData('item') + '>');
        this.append(document.getElementById(e.dataTransfer.getData('item')));
      }
    }
    let items = document.getElementsByClassName('item');
    for (let item of items) {
      item.ondragstart = e => {
        console.log('拖拽元素 ondragstart');
        e.dataTransfer.setData('item', e.target.id);
      }
      item.ondragend = e => {
       console.log('拖拽元素 ondragend');
      }
    }
  </script>
</body>
</html>
文章开头部分的 React 写的 demo
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="/UploadFiles/2021-04-02/react.development.js">

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

一句话新闻
一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?