在React中不依赖第三方库实现鼠标拖拽调整div大小的方法
纯React实现左右面板拖拽调整宽度方案(无第三方依赖)
1. 实现思路
- 监听拖拽元素的
mousedown事件标记拖拽开始 - 全局监听
mousemove事件计算鼠标水平位移,动态调整左侧面板宽度 - 全局监听
mouseup事件结束拖拽状态 - 通过CSS控制拖拽条固定在右侧面板左边缘,替代原生resize的右下角控件
2. 完整代码实现
React组件代码
import { useState, useRef, useCallback, useEffect } from 'react'; import './ResizablePanel.css'; const ResizablePanel = () => { // 左侧面板初始宽度,可根据需求调整 const [leftWidth, setLeftWidth] = useState(300); // 标记是否正在拖拽 const [isDragging, setIsDragging] = useState(false); // 存储拖拽开始时的鼠标X坐标和初始左侧宽度 const dragStartX = useRef(0); const startWidth = useRef(0); // 拖拽开始事件 const handleMouseDown = useCallback((e) => { setIsDragging(true); dragStartX.current = e.clientX; startWidth.current = leftWidth; // 拖拽时禁用文本选择,优化体验 document.body.style.userSelect = 'none'; }, [leftWidth]); // 拖拽中事件 const handleMouseMove = useCallback((e) => { if (!isDragging) return; const deltaX = e.clientX - dragStartX.current; // 可设置最小宽度避免面板过窄,这里最小设为100px,可自行修改 const newWidth = Math.max(100, startWidth.current + deltaX); setLeftWidth(newWidth); }, [isDragging]); // 拖拽结束事件 const handleMouseUp = useCallback(() => { setIsDragging(false); document.body.style.userSelect = 'auto'; }, []); // 全局监听鼠标移动和抬起事件 useEffect(() => { window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); return () => { window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); }; }, [handleMouseMove, handleMouseUp]); return ( <div id="container"> <div id="left_panel" style={{ width: `${leftWidth}px` }}> left content! </div> <div id="right_panel"> <div id="drag" onMouseDown={handleMouseDown}></div> right content! </div> </div> ); }; export default ResizablePanel;
对应CSS代码(ResizablePanel.css)
#container { display: flex; width: 100%; height: 400px; /* 可根据需求调整容器高度 */ border: 1px solid #eee; } #left_panel { flex-shrink: 0; height: 100%; background: #f5f5f5; padding: 16px; box-sizing: border-box; } #right_panel { position: relative; flex-grow: 1; height: 100%; padding: 16px; box-sizing: border-box; } #drag { position: absolute; left: 0; top: 0; width: 4px; height: 100%; background: #ddd; cursor: col-resize; transition: background 0.2s; } #drag:hover { background: #1677ff; }
3. 方案说明
- 完全基于React原生API和原生JS事件实现,无任何第三方依赖
- 拖拽条固定在两个面板的分界处,符合你需要的右边框位置需求
- 内置最小宽度限制,避免拖拽导致面板过窄,可根据需求调整阈值
- 拖拽过程中禁用全局文本选择,避免误选内容的体验问题
内容的提问来源于stack exchange,提问作者devb
相关产品推荐
相关产品推荐

