封装React组件DragLine,鼠标拖拽的边框改变元素宽度

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

在项目中,设计说想做个面板,其宽度随鼠标拖拽而变化,有最大最小值。基于这个小功能封装一个可拖拽组件,在需要的地方引入即可。

思路

这里只是实现x方向的拖拽,y轴拖拽思路差不多。
既然是鼠标操作,那肯定得监听鼠标事件,当鼠标按下(mouseDown)时,监听mouseMove事件和mouseUp事件,就是鼠标移动和抬起操作。然后计算出鼠标移动的宽度 = 元素现在的x坐标(clientX) - 起始坐标;然后把移动的宽度通过onChange函数返回给父组件,父组件改变自身的宽度。

代码示例

组件代码如下:

import React, { useRef, useState, useEffect } from 'react';
interface DragLineProps {style?: any; // 自定义样式className?: string; // 样式类名onChange: (width: number, height:number) => void; // 宽高变化函数
}const DragLine: React.FC<DragLineProps> = (props) => {const {style, className, onChange } = props;const containerRef = useRef<HTMLDivElement>(null);const [isDragging, setIsDragging] = useState(false);const initialMouseX = useRef(0); // 初始x值const initialMouseY = useRef(0); // 初始Y值useEffect(() => {const handleMouseMove = (event: MouseEvent) => {if (isDragging && containerRef.current) {const deltaX = event.clientX - initialMouseX?.current;const deltaY = event.clientY - initialMouseY?.current;// 调用父组件函数,传回移动的宽度或高度onChange(deltaX, deltaY)}};const handleMouseUp = () => {setIsDragging(false);};// 添加鼠标移动和抬起事件document.addEventListener('mousemove', handleMouseMove);document.addEventListener('mouseup', handleMouseUp);return () => {// 记得清除监听事件document.removeEventListener('mousemove', handleMouseMove);document.removeEventListener('mouseup', handleMouseUp);};}, [isDragging, initialMouseX, initialMouseY, onChange]);/** 监听鼠标按下事件 改变初始值 **/const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {event.preventDefault();setIsDragging(true);initialMouseX.current = event.clientX;initialMouseY.current =  event.clientY;};return (<divref={containerRef}className={className} style={style}onMouseDown={handleMouseDown}/>);};export default DragLine;

使用:
我这里是左侧面板可拖拽宽度,当然也可以是右侧面板,如需上下拖动,可以先定义高度,然后通过子组件调用handleChange传回的offsetY操作即可。

import React, { useState } from 'react';
import DragLine from '../../components/DragBox';
import './style.less';
const maxWidth = 300;
const minWidth = 100;
const App: React.FC = () => {const [width, setWidth] = useState(200);const handleChange = (offsetX: number, offsetY:number) => {const current = offsetX+ width;const newWidth = current > maxWidth ? maxWidth : current < minWidth ? minWidth : current;setWidth(newWidth);};return (<div className='DragWrapperRoot'><div style={{width}} className='dragBox'> 拖拽右侧边框改变盒子大小</div><DragLine onChange={handleChange} className="width-drag" style={{left: width}}/></div>);
};export default App;

less文件:

.DragWrapperRoot{position: relative;display: flex;height: 80%;.dragBox{position: relative;border-right: 1px solid #999;height: 100%;}.width-drag{position: absolute; cursor: ew-resize;  // 鼠标悬停双箭头样式top: 0;bottom: 0;width: 10px;background: transparent;}
}

总结

  1. 创建一个DragLine组件,接受一个onChange函数作为参数,该函数用于接收拖拽宽度的更新。
  2. 使用useRef钩子来获取<div>容器的引用,以便后续操作。
  3. 使用useState钩子来追踪拖拽状态,通过isDragging变量表示是否正在拖拽。
  4. 使用useEffect钩子来添加事件监听器,以便在鼠标移动和释放的过程中执行相应的操作。
  5. handleMouseMove回调函数中,根据鼠标位置和容器的左边界计算新的宽度和高度,并通过onChange函数将新的宽度传递给父组件。
  6. handleMouseUp回调函数中,将拖拽状态设置为false,表示拖拽结束。
  7. handleMouseDown回调函数中,将拖拽状态设置为true,表示开始拖拽。
  8. handleMouseDown函数绑定到容器的onMouseDown事件上,以便在鼠标按下时触发拖拽行为。
  9. 在组件的返回部分,使用ref将容器的引用与<div>元素关联起来。
  10. 通过添加适当的CSS样式,使得容器显示为竖线,并具有适当的拖拽光标效果。

DragLine`组件的思路是利用事件监听器来捕获鼠标的拖拽行为,计算拖拽宽度,并通过回调函数将更新后的宽度和高度传递给父组件。这样可以实现通过鼠标拖拽来改变容器宽度或者高度的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习路程之篇三、知识点、类、模块、项目、操作、下载、安装、IDEA

文章目录 1、IDEA开发工具2、IDEA的下载和安装3、IDEA中的第一个代码4、IDEAZ中的类、模块、项目的操作 1、IDEA开发工具 2、IDEA的下载和安装 3、IDEA中的第一个代码 4、IDEAZ中的类、模块、项目的操作

创建型设计模式-2.工厂设计模式

创建型设计模式-2.工厂设计模式 一、示例代码 下面是一个没有使用工厂设计模式的例子&#xff0c;ResourceLoader 类负责根据 URL 的前缀来加载资源。根据不同的前缀&#xff0c;它执行不同的操作来创建 Resource 对象。这导致了以下问题&#xff1a; 代码冗余&#xff1a;在…

【计算机视觉 | 图像分类】arxiv 计算机视觉关于图像分类的学术速递(7 月 17 日论文合集)

文章目录 一、分类|识别相关(11篇)1.1 Multimodal Distillation for Egocentric Action Recognition1.2 Dual-Query Multiple Instance Learning for Dynamic Meta-Embedding based Tumor Classification1.3 Interactive Spatiotemporal Token Attention Network for Skeleton-…

【面试官】说说你对闭包的理解

说说你对闭包的理解 闭包是什么闭包的三个特性优缺点应用场景javascript的垃圾回收原理:通常情况下有两种实现方式垃圾回收原理的缺陷GC优化策略 闭包是什么 闭包就是能够读取其他函数内部变量的函数闭包是指有权访问另一个函数作用域中变量的函数&#xff0c;创建闭包的最常见…

基于ClickHouse解决活动海量数据问题 | 京东云技术团队

1、背景 魔笛活动平台要记录每个活动的用户行为数据&#xff0c;帮助客服、运营、产品、研发等快速处理客诉、解决线上问题并进行相关数据分析和报警。可以预见到需要存储和分析海量数据&#xff0c;预估至少几十亿甚至上百亿的数据量&#xff0c;所以需要选择一款能存储海量数…

会议音响系统麦克风阵列波束形成算法C语言实现

一 应用麦克风阵列波束成形算法做的项目产品 二 麦克风波束形成技术应用领域? 麦克风波束形成技术是一种利用多个麦克风阵列来实现声音定向捕捉和增强的技术。通过对多个麦克风信号进行处理和合成,可以使麦克风系统在特定方向上具有更高的灵敏度和抑制非期望方向上的噪…

机器学习(13)--支持向量机

目录 一、支持向量机概述 二、Sklearn中的SVM概述 三、线性SVM损失函数 四、sklearn中进行可视化 1、导入模块 2、实例化数据集&#xff0c;可视化 3、网格点制作 4、建立模型并绘制决策边 目录 一、支持向量机概述 二、Sklearn中的SVM概述 三、线性SVM损失函数 四…

机器学习技术(三)——机器学习实践案例总体流程

机器学习实践案例总体流程 文章目录 机器学习实践案例总体流程一、引言二、案例1、决策树对鸢尾花分类1.数据来源2.数据导入及描述3.数据划分与特征处理4.建模预测 2、各类回归波士顿房价预测1.案例数据2.导入所需的包和数据集3.载入数据集&#xff0c;查看数据属性&#xff0c…

四个按键控制led的四种变化(按键控制led)(附源码)

文章目录 一、实验任务二、系统框图三、代码实现四、引脚分配五、总结 一、实验任务 使用开发板上的四个按键控制四个LED灯。按下不同的按键时&#xff0c;四个LED灯显示不同效果。本实验是在EP4CE6F17C8开发板上实现&#xff0c;仿真请用modelsim Altera 二、系统框图 三、代…

揭秘GPT-4;Adobe Firefly AI 扩大测试规模

&#x1f989; AI新闻 &#x1f680; Adobe Firefly AI 扩大测试规模&#xff0c;支持100多种语言的输入 摘要&#xff1a;Adobe宣布扩大测试规模&#xff0c;Adobe Firefly AI现在支持100多种语言的 prompts 输入。网页测试版Firefly已经扩充了罗马尼亚语等多种语言&#xf…

MacOS使用USB接口与IPhone进行Socket通信

演示效果如下: 开源地址: GitHub - rsms/peertalk: iOS and Mac Cocoa library for communicating over USB 克隆源码: git clone https://github.com/rsms/peertalk.git 克隆后打开peertalk然后启动xcode工程 先启动MacOS服务端工程,再启动iOS客户端工程 客户端 服务端

微信小程序安装和使用 Vant Weapp 组件库

微信小程序安装和使用 Vant Weapp 组件库 1. Vant Weapp 介绍2. Vant Weapp 的 安装2.1. 通过npm安装2.2. 构建npm2.3. 修改 app.json2.4. 修改 project.congfig.json2.5. 测试一下&#xff0c;使用Vant Weapp提供的组件 1. Vant Weapp 介绍 Vant 是一个轻量、可靠的移动端组件…

极智开发 | ubuntu交叉编译aarch64 boost

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多经验分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 ubuntu交叉编译aarch64 boost。 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xf…

opencv -10 基础运算之 图像加权和(图像融合图像修复视频合成)

什么是图像加权和&#xff1f; 所谓图像加权和&#xff0c;就是在计算两幅图像的像素值之和时&#xff0c;将每幅图像的权重考虑进来&#xff0c;可以用公式表示为&#xff1a; dst saturate(src1 &#x1d6fc; src2 &#x1d6fd; &#x1d6fe;)式中&#xff0c;satu…

C# Linq 详解二

目录 概述 七、OrderBy 八、OrderByDescending 九、Skip 十、Take 十一、Any 十二、All C# Linq 详解一 1.Where 2.Select 3.GroupBy 4.First / FirstOrDefault 5.Last / LastOrDefault C# Linq 详解二 1.OrderBy 2.OrderByDescending 3.Skip 4.Take 5.Any 6.All C#…

arm day2

汇编实现1到100的累加 .text .global _start_start:mov r0,#0loop:add r0,#1add r1,r0cmp r0,#100blne loopstop:b stop结果为0x13ba等于5050

python的魔法函数

一、介绍 在Python中&#xff0c;魔法函数是以双下划线__开头和结尾的特殊函数。它们在类定义中用于实现特定的行为&#xff0c;例如运算符重载、属性访问、迭代等。 以下是一些常见的Python魔法函数&#xff1a; __init__: 这是一个特殊的构造函数&#xff0c;在创建类的实例…

Web_php_include

代码审计 进入环境&#xff0c;根据题目的提示&#xff0c;本题考察文件包含漏洞 <?php show_source(__FILE__); echo $_GET[hello]; $page$_GET[page]; while (strstr($page, "php://")) {$pagestr_replace("php://", "", $page); } incl…

解决Ruoyi单体版本集成Echarts多图表时在Tab模式下不展示问题

目录 背景 一、Tab拆分后无法展示 1、环境简介 2、原始报表功能说明 3、tab切分遇到的问题 二、问题分析及解决 1、问题分析 2、问题解决 3、初始化时图表渲染 4、Tab切换时重渲 总结 背景 最近在使用ruoyi的单体化版本进行Echarts多图表展示时遇到一个问题&#xff0c;r…

苍穹外卖day03——菜品管理业务代码开发

目录 公共字段自动填充——问题分析和实现思路 公共字段自动填充——代码实现(1) 公共字段自动填充——代码实现完善(2) 新增菜品——需求分析与设计 产品原型 ​编辑 接口设计 ​编辑 数据库设计 新增菜品——代码开发1(文件上传接口) 配置文件 Controller层代码 前后…