React 实现列表拖动效果

React实现列表拖放 记录React实现列表拖放 我是站在巨人的肩膀上哈哈。原作者里面用的类实现,因为我需要用组件实现,所以进行了改动和备注。害怕原作者的编辑链接失效,所以记录一下。 原作者 React通过原生鼠标事件实现拖拽(drag and drop)列表重排序 根据实际情况进行改写。这里存在bug:如果列表中有输入内容,会导致不能输入等情况。应该是没有做事件捕获处理,解决了再来更。 import React, { useState } from "react"; import "./styles.css"; le 阅读详情

React 实现列表拖动效果

当我们想在 React 中实现一个列表拖动的效果的时候,有很多的第三方库(React dnd)可以借鉴,但是学习第三方库也是一个成本,或者拖动本身并不复杂,只需要第三方库的某一个 api 。这样情况下,我们可以自己实现一个。
在这里插入图片描述
组件源码
完成项目 欢迎 star
效果预览用户名:admin;密码:admin;

1. 使用 React 的鼠标事件

React 鼠标事件

在这里我们只会用到:onMouseDown、onMouseMove、onMouseUp 这三个鼠标事件

定义组件的 state

 state = {
    list: data, // 列表的数据
    dragging: false, // 是否开始拖`动`
    draggingIndex: -1, // 拖动元素的下标
    startPageY: 0, // 开始拖动的 Y 轴坐标
    offsetPageY: 0 // 拖动元素的位移
  }
2. 判断拖放的开始和结束

onMouseDown开始、onMouseUp结束

  1. 给列表的每一项添加一个onMouseDown事件监听
<List.Item 
    onMouseDown={(e) => this.dragging(e, index)}
    >
  {item}
</List.Item>
  1. 当鼠标按下的时候我们初始化组件的状态。
  // 点击的时候记录 Y 轴的位置 
dragging = (e, index) => {
  this.setState({
    dragging: true, 
    draggingIndex: index, 
    currentPageY: e.pageY, // 只需要纵向移动 
    startPageY: e.pageY,
  })
}
  1. 给点击的元素添加样式,让我们知道要拖动谁。
<List.Item 
    onMouseDown={(e) => this.dragging(e, index)}
   	style={this.getDraggingStyle(index)}
    >
  {item}
</List.Item>
// 移动动画
getDraggingStyle = (index) => {
  if (index !== this.state.draggingIndex) return
  return {
    backgorundColor: '#eee',
    transform: `translate(10px,${this.state.offsetPageY}px)`, // 下面会介绍
    opacity: 0.5
  }
}
3. 实现拖放元素的位移效果

效果:拖放的元素视觉效果上要脱离列表本身,在列表上下进行移动。

如何实现:

  1. 需要对onMouseMove进行监听。

    1. 在哪里进行监听 ?列表本身?

      首先不能在列表本身进行监听,也不能在父容器监听,因为鼠标移动的范围是屏幕的大小(暂时这么设定),那么只有在 document 上进行监听吗 ?

      其实我们可以设置一个遮罩层,在它上面进行onMouseMove、onMouseUp的事件监听。

      <List
        dataSource={this.state.list}
        renderItem={(item, index) => (
          <List.Item onMouseDown={(e) => this.dragging(e, index)} key={item}
            style={this.getDraggingStyle(index)}
            >
            {item}
          </List.Item>
        )}
        />
      {/* 用一个遮罩监听事件,也可以监听整个 document */}
      {
        this.state.dragging && (
          <div
            style={maskStyle}
            onMouseUp={e => this.onMouseUp(e)}
            onMouseMove={e => this.onMouseMove(e)}
            >
          </div>
        )
      }
      
      const maskStyle = {
        position: 'fixed',
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        backgorund: 'rgba(0,0,0,0.5)'
      }
      
  2. 需要记录 onMouseMove 移动的轨迹(offset),列表跟随鼠标进行移动。

    1. 需要记录从起点移动到终点的距离(offset),记录移动元素的下标。
    2. 根据移动距离是否大于行高判断是向上移动,还是向下移动。
    3. 移动的过程更新 offsetPageY 然后借助 CSS3 动画进行移动。
// 移动的轨迹
onMouseMove = (e) => {
  let offset = e.pageY - this.state.startPageY
  const draggingIndex = this.state.draggingIndex
  if (offset > lineHeight && draggingIndex < this.state.list.length) {
    //  向下移动
    offset -= lineHeight
  } else if (offset < -lineHeight && draggingIndex > 0) {
    // 向上移动
    offset += lineHeight
  }
  // item 移动的距离
  this.setState({ offsetPageY: offset })
}
4. 更新拖放后的数据

移动的过程中更新列表的数据

// 重新计算数组,插入一个,删除一个。不断地插入删除(每隔一行)。
const move = (arr = [], startIndex, toIndex) => {
  arr = arr.slice()
  arr.splice(toIndex, 0, arr.splice(startIndex, 1))
  return arr;
}

更新数据

onMouseMove = (e) => {
  let offset = e.pageY - this.state.startPageY
  const draggingIndex = this.state.draggingIndex
  if (offset > lineHeight && draggingIndex < this.state.list.length) {
    //  向下移动
    offset -= lineHeight
     // 按照移动的方向进行数据交换
    this.setState({
      list: move(this.state.list, draggingIndex, draggingIndex + 1),
      draggingIndex: draggingIndex + 1,
      startPageY: this.state.startPageY + lineHeight
    })
  } else if (offset < -lineHeight && draggingIndex > 0) {
    // 向上移动
    offset += lineHeight
    this.setState({
      list: move(this.state.list, draggingIndex, draggingIndex - 1),
      draggingIndex: draggingIndex - 1,
      startPageY: this.state.startPageY - lineHeight
    })
  }

向上移动 draggingIndex-1 ,向下移动 draggingIndex+1 。

每移动一行,数据更新一次,0 移动到 2 的位置,需要先移动到 1 ,然后从 1 的位置开始重新计算位移,然后由 1 的位置移动到 2 。以此类推。类似冒泡排序。

5. 结束拖放
// 松开鼠标的时候,重新初始化 startPageY、draggingIndex,
onMouseUp = (e) => {
  this.setState({
    dragging: false,// 移除遮罩
    startPageY: 0, 
    draggingIndex: -1
  })
}

这只是一个很简单场景实现(列表的简单排序),如需功能强大的拖动还是需要第三方库来实现。

React +TS实现拖拽列表 最近使用React写的拖拽组件,分享给大家,直接上代码。 阅读详情

相关推荐

react实现拖拽

react实现拖拽 1.先下载react的项目 步骤:1.创建一个新的文件夹cmd访问2.输入命令 npm install -g create-react-app 然后 create-react-app my-new-app(my-new-app为文件夹名称,可自定义) 2.在src下创建新的文件夹,然后在新的文件夹下创建js文件跟css文件,在js文件里面 import React from 'react' import './tzs.css' class Drag extends React.Com

weixin_57157220的博客 885

React原生拖拽API实现拖拽及带动画的排序

需求: React原生拖拽API实现拖拽及带动画的排序 难点: React原生拖拽各个API函数的用途 排序动画的实现思路 实现过程: ​ 拖拽变换位置还算比较顺利,只要拖拽API了解就问题不大,感觉难点主要在动画的实现,动画的实现主要参考了该文章:js drag拖动排序,但需求上有两点跟该文章的不太一样:一个是用React实现,还有就是该文章的动画思路是先替换dom元素的位置再进行动画效果展示。然后我打算先动画再替换位置。 该文章的动画具体实现思路如下: 先记录两个元素的位置,再将dom元素进行替换位

qq_36550828的博客 962

前端拖拽事件解析-react实现拖拽效果demo

前言 在平时开发中会有一些涉及到通过拖拽效果完成的业务需求,那么我们就需要了解和学习拖拽相关的知识,在html5中就有原生的拖拽api,下面就来使用这些api实现一个灵活拖拽的demo。 拖拽流程 简单来说完成拖拽一共需要三步: 开始拖拽 -> 拖拽中 -> 结束拖拽。 在这些步骤中又会有许多更细节的步骤需要处理,完整流程如下: 1、设置指定元素为可拖拽元素(使用draggable属性,只有设置了draggable属性,元素才可以被拖动) 2、点击拖拽元素开始进行拖拽并监听拖拽开始事件(设置拖拽

前端三脚猫的博客 5317

React实现拖拽效果

使用react完成拖拽功能

前端 2460

React通过原生鼠标事件实现拖拽(drag and drop)列表重排序

虽然现在html5已经有支持拖拽的事件,但是支持还不那么全面。所以目前大部分的拖拽还是通过原生的鼠标事件来实现列表重新排序。话不多说。一步步开始做吧 盆友们可以通过下面链接查看所有代码和效果。 https://codesandbox.io/s/drap-and-drop-to-reorder-list-iqwqj Step1.准备一个模拟数据 let list = []; for(let i = 0; i< 10; i++){ list.push(`item ${i}`); } Step2

莫小猪的菜鸟进阶路 3322

ReactJS实现列表拖动排序交互功能实战

htmltable {th, td {th {pre {简介:在ReactJS中,列表拖动排序是一项提升用户界面体验的重要交互功能。通过监听鼠标事件(如mousedown、mousemove、mouseup),结合组件状态管理与事件处理函数,可实现流畅的拖拽排序效果。

weixin_35266799的博客 860

react+ts实现小球交叉,小球互推,并高亮

代码tsx部分 import { Component, createRef } from "react"; import './xian.less'; interface Props { } interface State { Num: number, MaxNum: number, Rightlist: xian[] Leftlist: xian[] } interface xian { id: string, text: number }

m0_60584958的博客 136

前端交互:实现鼠标拖动列表的技巧

HTML5拖放API允许开发者通过拖放接口实现交互功能,从而提升用户体验。它包括了拖动源(draggable)和放置目标(droppable)两个主要元素,以及一系列相关的事件,如dragstartdragdragenddragover和drop。这些事件使得用户能够通过拖动来选择元素,并将其放置在目标位置。Data Transfer对象是拖放操作中一个核心组件,它允许开发者在拖动源和放置目标之间传递数据。这个对象是事件对象的一个属性,具体来说是dragstartdrag。

weixin_35829279的博客 1361

react项目中使用react-dnd实现列表的拖拽排序

现在有一个新需求就是需要对一个列表,实现拖拽排序的功能,要实现的效果如下图: 可以通过 react-dnd 或者 react-beautiful-dnd 两种方式实现,今天先讲下使用react-dnd是如何实现的,github地址: https://react-dnd.github.io/react-dnd/docs/api/dnd-provider 1.先安装依赖 npm ire...

songxueing的博客 1万+

React Native拖动排序功能实战详解

React Native由Facebook于2015年开源,旨在让开发者能使用JavaScript来构建跨平台的移动应用。在此之前,开发跨平台应用通常需要重复编写大量的代码以适配不同的操作系统,这不仅耗时而且效率低下。React Native的出现,通过使用JavaScript与本地组件的桥接,让开发者能够编写一次代码,并在iOS和Android设备上运行,极大地提升了开发效率和用户体验。React Native从最初发布至今,经历了多个版本迭代,功能不断优化,社区支持也在持续增长。

weixin_28736145的博客 1090

MiniMAX H3官方SKILL三段式提示词模板与本地部署全解

视频生成模型的效果高度依赖于提示词的结构与质量,而提示词工程正是连接自然语言与视觉表达的关键桥梁。在文本模型之外,视频模型对场景、角色、镜头动作的信息层次更为敏感,普通自由描述往往导致画面漂移、风格不稳定。MiniMAX H3 作为社区热议的视频生成模型,通过一套官方 SKILL 三段式提示词模板,将环境、主体、镜头动作分类组织,免API、免推理即可稳定产出风格统一的素材。这一设计不仅降低了提示词编写门槛,也提升了多轮生成的复用性,适合短视频生产、影视概念设计及自动化视频流水线等场景。本文围绕该模板的结构与

weixin_33309048的博客 1168

react实现一个列表的拖拽排序(react实现拖拽)

比较流行的有react-beautiful-dnd和dnd-kit,可能还有react-sortable-hoc,不过这个好像已经不再维护了。我的项目里使用了antd,antd表格有一个示例还是挺像的,本来我想用Table实现,它自带拖拽。这个作者最后推荐了dnd-kit所以我最后选择了这个库,但其实我这个需求用react-beautiful-dnd‌ 也能实现。您还需要确保安装了对等依赖项。这里有两个版本,我不想用immutability-helper库,觉得多一个依赖没啥意义,所以我去掉了。

从事前端,不断积累经验,学习新的技术。头像不是本人是莉莉崽(美貌、可爱集于一身的小姐姐,小仙女),一个宝藏博主,值得喜欢! 3693

从按键开机到I2C隔离:手把手拆解一个智能硬件项目里的MOS管实战配置

本文详细解析了智能硬件项目中MOS管的实战配置,从按键开机电路到I2C总线隔离,全面覆盖电源管理和信号隔离的关键技术。通过PMOS+NMOS组合方案实现可靠的开机功能,并采用双NMOS方案优化I2C通信隔离,提升系统稳定性和信号质量。

weixin_28691741的博客 326

react-draggable实现拖拽详解

在页面中导入react-draggable。2. 初始化开始位置。

hyqhyqhyqq的博客 5815

UM2 3D 打印机 DIY 实践 (2) 电路篇

涉及到的东西非常多,实际上后面还会讲到。主要部件清单: 主板 mega2560 + Ramps1.4 + LCD12864 各一张 42 x38mm x3,xyz 轴各一台 42 x23mm x1,用在挤出机 泰坦远程挤出机 x1 TMC2225 驱动板 x4, 替代a4988、TMC2208,静音效果好,性价比高 s-250-12v 20A开关电源 x1。功率必须足够大,宁可选大一点的 大功率 MOS 管,25A x1 NTC .

afeiqiang的专栏 3601

Claude Skills:不是更聪明,而是更“像专家”的 Agent 养成方法

Claude Skills 不是在告诉 Agent“你能做什么”, 而是在约束它“你应该如何思考、如何判断、如何给结论”。

测试者家园 1293

如何在React项目中实现一个可拖拽排序的列表组件,实现列表项的拖拽和排序功能,需要考虑哪些技术细节包括动画效果和用户交互逻辑以及性能优化?

以下是一个完整的 React 可拖拽排序列表组件,包含模拟数据请求、数据更新和性能优化,同时提供了相应的样式,你可以直接复用。

前端大白话 1275

智能体异常行为检测-基于行为序列的异常模式识别技术【附代码】

在多智能体系统(Multi-Agent Systems, MAS)中,智能体之间的行为协调与自主决策是系统稳定运行的关键。然而,当某个智能体因策略偏移、环境变化或潜在攻击而出现**异常行为(Abnormal Behavior)**时,整个系统可能陷入混乱或崩溃。

一键难忘的博客 1143

html5多个图片位置_React 实现简易的图片拖动排序

基本介绍 ????在 web 页面中,如果需要改变多个元素的位置,可以通过元素拖动来实现。HTML5中加入了一个全局属性draggable,通过设置该属性的值为true/false来控制元素是否可拖动。需要注意的是:链接和图片默认是可拖动的,可以通过将draggable设置为false将他们变为不可拖动元素。Internet Explorer 8 及更早 IE 版本不支持dragga...

weixin_39830688的博客 733

【TC3xx芯片】TC3xx芯片STM介绍

TC3xx芯片STM介绍

qq_36056498的博客 2280

基于JeecgBoot 3.9.0 开源项目的企业管理平台

基于JeecgBoot 3.9.0 开源项目的企业管理平台

宁波阿成的博客 371

【亲测免费】 React Native可拖动FlatList组件教程

**React Native Draggable FlatList** 是一个专门为React Native设计的可拖放列表组件。它允许用户通过简单的手势来重新排序列表项,提供了一种动态调整数据视图的方式。该项目基于FlatList构建,支持动画效果,并且兼容[Reanimated](https://github.com/software-mansion/react-native-reanimat...

gitblog_00963的博客 748

New API 大模型网关保姆级教程:Docker Compose 部署 + MiniMax 接入 Claude 实战

New API 是一个开源的 AI 基座平台,提供统一的 API 接口接入 30+主流 AI 服务(如 OpenAI、Claude 等)。核心功能包括智能路由、精细计费、安全管控和多租户支持,采用 AGPLv3 协议开源。支持 Docker Compose 快速部署,通过修改配置文件即可连接不同数据库,适合从开发到生产环境的不同规模应用。部署时需注意修改默认密码等安全配置。

甘蓝的专栏 1602

react 实现表格列表拖拽排序

在项目开发中,遇到这样一个需求:需要对表格里面的数据进行拖拽排序。

二三的博客 4903

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: 安卓9.0 http请求数据失败解决办法
下一篇: React & Redux 进阶
composurext
博客等级 码龄10年 15粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值