返回

自己就能实现的 React 列表拖动效果

前端

使用原生 JavaScript 实现 React 中的列表拖放功能

前言

在 React 中实现列表拖放功能通常会用到第三方库,如 React DnD,但学习第三方库会增加学习成本。对于较为简单的拖放操作,我们可以选择自己实现拖放功能。本文将详细介绍如何使用原生 JavaScript 实现 React 中的列表拖放效果,包括获取列表元素 ID、处理拖放事件和优化样式。

获取列表元素 ID

第一步是获取要拖放的列表元素的 ID。为此,我们在 <li> 元素上添加 draggable 属性并指定一个 onDragStart 事件处理程序。在 onDragStart 处理程序中,我们将列表元素的 ID 设置为拖放数据的类型为 text/plain 的值。

const List = () => {
  const handleDragStart = (e, item) => {
    e.dataTransfer.setData('text/plain', item.id);
  };

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id} draggable onDragStart={(e) => handleDragStart(e, item)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
};

处理拖放事件

接下来,我们需要处理目标列表上的拖放事件。在 <ul> 元素上添加 onDroponDragOver 事件处理程序。onDrop 处理程序接收拖放数据并更新目标列表中的项目,而 onDragOver 处理程序阻止浏览器执行默认操作(如打开链接)。

const DroppableList = () => {
  const handleDrop = (e) => {
    const id = e.dataTransfer.getData('text/plain');
    // ...更新目标列表...
  };

  return (
    <ul onDrop={handleDrop} onDragOver={(e) => e.preventDefault()}>
      {items.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
};

样式优化

为了美化拖放效果,我们可以添加一些 CSS 样式。例如,我们可以将 li 元素的 cursor 属性设置为 move,以指示该元素可拖动。我们还可以添加一个 .dragged 类,当元素被拖动时应用该类,以改变元素的外观。

ul {
  list-style-type: none;
  display: flex;
  flex-direction: column;
  padding: 0;
}

li {
  padding: 10px;
  margin: 5px;
  background-color: #eee;
  cursor: move;
}

.dragged {
  background-color: #ccc;
}

完成的实现

通过以上步骤,我们已经实现了 React 中的基本列表拖放功能。以下是完整的实现代码:

const List = () => {
  const handleDragStart = (e, item) => {
    e.dataTransfer.setData('text/plain', item.id);
  };

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id} draggable onDragStart={(e) => handleDragStart(e, item)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
};

const DroppableList = () => {
  const handleDrop = (e) => {
    const id = e.dataTransfer.getData('text/plain');
    // ...更新目标列表...
  };

  return (
    <ul onDrop={handleDrop} onDragOver={(e) => e.preventDefault()}>
      {items.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
};
ul {
  list-style-type: none;
  display: flex;
  flex-direction: column;
  padding: 0;
}

li {
  padding: 10px;
  margin: 5px;
  background-color: #eee;
  cursor: move;
}

.dragged {
  background-color: #ccc;
}

结论

通过使用原生 JavaScript,我们能够在 React 中实现一个简单的列表拖放功能。这种方法既灵活又有效,可以让我们根据自己的需求定制拖放行为。

常见问题解答

  1. 可以对列表元素进行排序吗?

是的,我们可以通过在 onDrop 处理程序中重新排列目标列表中的项目来实现排序。

  1. 可以将项目拖放到另一个列表中吗?

是的,我们可以通过在 onDrop 处理程序中更新两个列表中的项目来实现跨列表拖放。

  1. 如何处理多选?

我们可以使用 dataTransfer.getData() 获取一个数组,其中包含所选项目的 ID,然后更新目标列表以反映这些选择。

  1. 如何阻止拖放某些项目?

我们可以通过检查拖放的元素是否属于某个类或包含某个属性来阻止拖放。

  1. 如何添加动画效果?

我们可以使用 CSS 动画或 JavaScript 库(如 GSAP)来添加动画效果,以增强拖放体验。