返回顶部
首页 > 资讯 > 前端开发 > JavaScript >react实现自定义拖拽hook
  • 720
分享到

react实现自定义拖拽hook

2024-04-02 19:04:59 720人浏览 独家记忆
摘要

前沿 最近发现公司的产品好几个模块用到了拖拽功能,之前拖拽组件是通过HTML5 drag api 实现的但体验并不是很好,顺便将原来的拖拽组建稍做修改,写一个自定义hook,方便大家

前沿

最近发现公司的产品好几个模块用到了拖拽功能,之前拖拽组件是通过HTML5 drag api 实现的但体验并不是很好,顺便将原来的拖拽组建稍做修改,写一个自定义hook,方便大家使用拖拽功能。

正文

拖拽功能原理:

1、拖拽元素通过addEventListener监听器添加鼠标按下,鼠标移动,以及鼠标抬起事件。
2、再通过getBoundinGClientRect() 得到拖拽元素四周相对于可拖拽区域边界的距离。
3、鼠标移动时计算x轴和y轴的移动偏移量。
4、通过element.style.transfORM 设置元素移动。
5、每次拖拽完成后,都将此次偏移量保存,下次再次拖拽时,可以保证位置的实时性。

代码开发:

useDrag.jsx

import { useEffect, useState } from "React";

export default function useDrag({ dragger, draggerBox = dragger, container = document.body, maring = [0, 0, 0, 0] }) {
  const [translateX, setTranslateX] = useState(0); // 水平方向偏移量
  const [translateY, setTranslateY] = useState(0); // 垂直方向偏移量

  useEffect(() => {
    if (!dragger) return;
    if (!draggerBox) return;
    if (!container) return;
    dragger = typeof dragger === 'string' ? document.querySelector(dragger) : dragger; // 根据传入的值类型,去查找使用元素
    draggerBox = typeof draggerBox === 'string' ? document.querySelector(draggerBox) : draggerBox;
    container = typeof container === 'string' ? document.querySelector(container) : container;
    
    const { left: containerL, top: containerT, right: containerR, bottom: containerB } = container.getBoundingClientRect(); // 获取可拖拽区域边界位置

    const onMouseDown = event => {
      const initMouseX = event.clientX; // 元素初始水平坐标值
      const initMouseY = event.clientY;// 元素初始垂直坐标

      const { left: boxL, top: boxT, right: boxR, bottom: boxB } = draggerBox.getBoundingClientRect(); // 获取拖拽实体的位置

      let deltaMouseX; // 实际水平偏移量
      let deltaMouseY; // 实际垂直增量值

      const onMouseMove = event => {
        const moveMouseX = event.clientX; // 元素移动后水平坐标值
        const moveMouseY = event.clientY; // 元素移动后垂直坐标值

        let deltaX = moveMouseX - initMouseX; // 当前移动水平相对移动距离
        let deltaY = moveMouseY - initMouseY; // 当前移动垂直相对移动距离

        if (boxL + deltaX < containerL + maring[0]) { // 当元素左边框+水平相对移动距离 < 可拖拽区域左边界+左边距时 (说明元素已经超出左侧边界)
        
          deltaX = containerL + maring[0] - boxL;
        }

        if (boxR + deltaX > containerR - maring[1]) { // 当元素右边框+水平相对移动距离 > 可拖拽区域右边界+右边距时 (说明元素已经超出右侧边界)
          deltaX = containerR - maring[1] - boxR;
        }

        if (boxB + deltaY > containerB - maring[2]) { // 当元素下边框+垂直相对移动距离 > 可拖拽区域下边界+下边距时 (说明元素已经超出下侧边界)
          deltaY = containerB - maring[2] - boxB;
        }

        if (boxT + deltaY < containerT + maring[3]) { // 当元素上边框+垂直相对移动距离 < 可拖拽区域上边界+上边距时 (说明元素已经超出上侧边界)
          deltaY = containerT + maring[3] - boxT
        }

        deltaMouseX = deltaX + translateX; // 实际水平偏移量
        deltaMouseY = deltaY + translateY; // 实际垂直偏移量
        
        draggerBox.style.transform = `translate(${deltaMouseX}px, ${deltaMouseY}px)`;
      };

      const onMouseUp = () => {
        setTranslateX(deltaMouseX); // 保存上次水平偏移量
        setTranslateY(deltaMouseY); // 保存上次垂直偏移量
        window.removeEventListener('mousemove', onMouseMove);
        window.removeEventListener('mouseup', onMouseUp);
      }
      window.addEventListener('mousemove', onMouseMove);
      window.addEventListener('mouseup', onMouseUp);
    }
    dragger.addEventListener('mousedown', onMouseDown);

    return () => dragger.removeEventListener('mouseup', onMouseDown);
  }, [dragger, draggerBox, container, maring])
}

使用方法:

import React from 'react';
import useDrag from '../hooks/useDrag'
import './index.less';

function Test() {
  useDrag({ dragger: '.dragger', draggerBox: '.draggerBox', container: '.container', maring: [10, 10, 10, 10]})

  return (
    <div className='container'>
      <div className='draggerBox'>
        <div className='dragger'>
        </div>
      </div>
    </div>
  )
}

export default Test;
.container{
  width: 800px;
  height: 800px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -400px 0 0 -400px;
  border: 2px solid green;
}

.draggerBox{
  width: 200px;
  height: 300px;
  border: 1px solid red;
}

.dragger{ 
  width: 100%;
  height: 50px;
  background: blue;
}

效果展示

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

--结束END--

本文标题: react实现自定义拖拽hook

本文链接: https://lsjlt.com/news/166036.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • react实现自定义拖拽hook
    前沿 最近发现公司的产品好几个模块用到了拖拽功能,之前拖拽组件是通过Html5 drag Api 实现的但体验并不是很好,顺便将原来的拖拽组建稍做修改,写一个自定义hook,方便大家...
    99+
    2024-04-02
  • React如何自定义hook
    本篇内容主要讲解“React如何自定义hook”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React如何自定义hook”吧!什么是hookHook是 React 16.8 的新增特性。它通常与...
    99+
    2023-07-02
  • 详解React自定义Hook
    目录前言如何自定义 Hooks组件之间共享逻辑自定义 Hooks 允许你共享有状态逻辑,而不是状态本身分类功能型 HooksuseWindowWidthuseLocalStorage...
    99+
    2023-05-17
    React自定义Hook React Hook
  • React自定义hook的方法
    目录什么是hook常用的有哪些hook自定义hook什么是hook Hook是 React 16.8 的新增特性。它通常与函数式组件同时使用。可以使函数式组件在不编写 class 的...
    99+
    2024-04-02
  • Android自定义View实现可以拖拽的GridView
    先看看效果图 主要思想: 1、监听触碰事件 2、用WindowManager添加拖曳的图片 3、用Collections.swap()交换List数据 自定义代码: pu...
    99+
    2022-06-06
    view gridview Android
  • Android----ViewDragHelper(自定义拖拽) ---- 之一
    功能 自定义可以拖拽的view 创建流程 创建自定义 可以拖拽的 viewGroup 实例化 viewDragHelper callback 内部方法 重写 xml布局中添加 简单的代码实现 package com.field.dr...
    99+
    2022-06-06
    自定义 viewdraghelper Android
  • react-dnd如何实现拖拽
    这篇文章主要介绍了react-dnd如何实现拖拽的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇react-dnd如何实现拖拽文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2024-04-02
  • 怎么实现react拖拽hooks
    这篇文章主要介绍了怎么实现react拖拽hooks,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言源码总共也就一百多行,看完这个大致可以理解一些成熟的react拖拽库的实现...
    99+
    2023-06-14
  • react实现拖拽模态框
    前言 实际开发中,模态框展现数据会经常出现.但不幸的是有时功能开发完了,UI同学突然提出需求希望模态框能拖拽.本文使用的模态框由 ant design 3.0 的 Modal 组件封...
    99+
    2024-04-02
  • 深入理解React的自定义Hook
    自定义 Hooks 的核心是共享组件之间的逻辑。使用自定义 Hooks 能够减少重复的逻辑,更重要的是,自定义 Hooks 内部的代码描述了它们想做什么,而不是如何做。当你将逻辑提取到自定义Hooks 中时,你可以隐藏如何处理某些"...
    99+
    2023-05-14
    前端 代码规范 React.js
  • Android自定义ListView实现仿QQ可拖拽列表功能
    我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定...
    99+
    2022-06-06
    列表 listview Android
  • VUE3中如何实现拖拽与缩放自定义看板
    本文小编为大家详细介绍“VUE3中如何实现拖拽与缩放自定义看板”,内容详细,步骤清晰,细节处理妥当,希望这篇“VUE3中如何实现拖拽与缩放自定义看板”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. npm下载拖...
    99+
    2023-07-05
  • 自定义input组件怎么实现拖拽文件上传
    这篇“自定义input组件怎么实现拖拽文件上传”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“自定义input组件怎么实现拖拽...
    99+
    2023-07-05
  • android自定义可拖拽的仪表盘
    本文实例为大家分享了android自定义可拖拽的仪表盘的具体代码,供大家参考,具体内容如下 因为项目最近需要用到仪表盘,又不想使用之前使用的背景图的方式。主要是想自己写一点代码。觉得...
    99+
    2024-04-02
  • React自定义Hook-useForkRef的具体使用
    目录开篇思路实现自定义 Hook - useForkRef开篇 使用过 React 技术栈的同学相信都使用过 ref 传递给 render 中的元素,而在使用 React 封装组件时...
    99+
    2024-04-02
  • Vue全局自定义指令Modal拖拽的实践
    目录背景 实现思路 实现效果 背景 最近一直在做的项目是Vue2搭建的项目,UI框架用的antdV,项目中用到了很多Modal对话框,然后突然有一天产品说:“这个对话框为什么不能移...
    99+
    2024-04-02
  • react中实现拖拽排序react-dnd功能
    dnd文档 html 拖拽排序 import React, { useState, useRef } from 'react'; import { cloneDeep } from...
    99+
    2023-02-06
    拖拽排序react-dnd react拖拽排序
  • 详解Android自定义view如何实现拖拽选择按钮
    小编这次要给大家分享的是详解Android自定义view如何实现拖拽选择按钮,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。本文实例为大家分享了Android实现拖拽选择按钮的具体代码,供大家参考,具体...
    99+
    2023-05-30
    android view roi
  • Android如何实现自定义可拖拽的悬浮按钮DragFloatingActionButton
    这篇文章主要介绍Android如何实现自定义可拖拽的悬浮按钮DragFloatingActionButton,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!悬浮按钮FloatingActionButton是Androi...
    99+
    2023-05-31
    android
  • Vue+element自定义指令如何实现表格横向拖拽
    目录element自定义指令实现表格横向拖拽自定义指令设置及常用自定义指令指令定义函数提供了几个钩子函数(可选)下面分享几个实用的 Vue 自定义指令element自定义指令实现表格...
    99+
    2022-11-13
    Vue element 自定义指令 表格横向拖拽
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作