原文合集地址如下,有需要的朋友可以關(guān)注
本文地址
合集地址
在項(xiàng)目中,設(shè)計(jì)說想做個(gè)面板,其寬度隨鼠標(biāo)拖拽而變化,有最大最小值。基于這個(gè)小功能封裝一個(gè)可拖拽組件,在需要的地方引入即可。
思路
這里只是實(shí)現(xiàn)x方向的拖拽,y軸拖拽思路差不多。
既然是鼠標(biāo)操作,那肯定得監(jiān)聽鼠標(biāo)事件,當(dāng)鼠標(biāo)按下(mouseDown)時(shí),監(jiān)聽mouseMove事件和mouseUp事件,就是鼠標(biāo)移動(dòng)和抬起操作。然后計(jì)算出鼠標(biāo)移動(dòng)的寬度 = 元素現(xiàn)在的x坐標(biāo)(clientX) - 起始坐標(biāo);然后把移動(dòng)的寬度通過onChange函數(shù)返回給父組件,父組件改變自身的寬度。
代碼示例
組件代碼如下:
import React, { useRef, useState, useEffect } from 'react';
interface DragLineProps {
style?: any; // 自定義樣式
className?: string; // 樣式類名
onChange: (width: number, height:number) => void; // 寬高變化函數(shù)
}
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;
// 調(diào)用父組件函數(shù),傳回移動(dòng)的寬度或高度
onChange(deltaX, deltaY)
}
};
const handleMouseUp = () => {
setIsDragging(false);
};
// 添加鼠標(biāo)移動(dòng)和抬起事件
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
return () => {
// 記得清除監(jiān)聽事件
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
}, [isDragging, initialMouseX, initialMouseY, onChange]);
/** 監(jiān)聽鼠標(biāo)按下事件 改變初始值 **/
const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
event.preventDefault();
setIsDragging(true);
initialMouseX.current = event.clientX;
initialMouseY.current = event.clientY;
};
return (
<div
ref={containerRef}
className={className}
style={style}
onMouseDown={handleMouseDown}
/>
);
};
export default DragLine;
使用:
我這里是左側(cè)面板可拖拽寬度,當(dāng)然也可以是右側(cè)面板,如需上下拖動(dòng),可以先定義高度,然后通過子組件調(diào)用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'>
拖拽右側(cè)邊框改變盒子大小
</div>
<DragLine onChange={handleChange} className="width-drag" style={{left: width}}/>
</div>
);
};
export default App;
less文件:文章來源:http://www.zghlxwxcb.cn/news/detail-567366.html
.DragWrapperRoot{
position: relative;
display: flex;
height: 80%;
.dragBox{
position: relative;
border-right: 1px solid #999;
height: 100%;
}
.width-drag{
position: absolute;
cursor: ew-resize; // 鼠標(biāo)懸停雙箭頭樣式
top: 0;
bottom: 0;
width: 10px;
background: transparent;
}
}
總結(jié)
- 創(chuàng)建一個(gè)
DragLine
組件,接受一個(gè)onChange
函數(shù)作為參數(shù),該函數(shù)用于接收拖拽寬度的更新。 - 使用
useRef
鉤子來獲取<div>
容器的引用,以便后續(xù)操作。 - 使用
useState
鉤子來追蹤拖拽狀態(tài),通過isDragging
變量表示是否正在拖拽。 - 使用
useEffect
鉤子來添加事件監(jiān)聽器,以便在鼠標(biāo)移動(dòng)和釋放的過程中執(zhí)行相應(yīng)的操作。 - 在
handleMouseMove
回調(diào)函數(shù)中,根據(jù)鼠標(biāo)位置和容器的左邊界計(jì)算新的寬度和高度,并通過onChange
函數(shù)將新的寬度傳遞給父組件。 - 在
handleMouseUp
回調(diào)函數(shù)中,將拖拽狀態(tài)設(shè)置為false
,表示拖拽結(jié)束。 - 在
handleMouseDown
回調(diào)函數(shù)中,將拖拽狀態(tài)設(shè)置為true
,表示開始拖拽。 - 將
handleMouseDown
函數(shù)綁定到容器的onMouseDown
事件上,以便在鼠標(biāo)按下時(shí)觸發(fā)拖拽行為。 - 在組件的返回部分,使用
ref
將容器的引用與<div>
元素關(guān)聯(lián)起來。 - 通過添加適當(dāng)?shù)腃SS樣式,使得容器顯示為豎線,并具有適當(dāng)?shù)耐献Ч鈽?biāo)效果。
DragLine`組件的思路是利用事件監(jiān)聽器來捕獲鼠標(biāo)的拖拽行為,計(jì)算拖拽寬度,并通過回調(diào)函數(shù)將更新后的寬度和高度傳遞給父組件。這樣可以實(shí)現(xiàn)通過鼠標(biāo)拖拽來改變?nèi)萜鲗挾然蛘吒叨鹊墓δ堋?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-567366.html
到了這里,關(guān)于封裝React組件DragLine,鼠標(biāo)拖拽的邊框改變元素寬度的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!