You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件顶部边框拖拽调整大小实现方案咨询

Hey there! 很高兴你已经有了用state管理高度的思路,这完全踩中了React的核心思想——咱们就沿着这个方向走,完全不用依赖jQuery或者直接操作DOM,纯React原生就能实现这个拖拽调整高度的功能。

实现思路与代码示例

核心逻辑是通过监听鼠标的mousedown、mousemove、mouseup事件计算高度变化,全程用React的state驱动视图更新,完全贴合React的数据驱动理念。

1. 组件基础结构与状态定义

先搭建抽屉的基本结构,把高度存在state中,同时给顶部拖拽手柄绑定mousedown事件:

import { useState, useRef, useEffect } from 'react';

const DraggableDrawer = () => {
  // 抽屉初始高度,可根据需求调整
  const [drawerHeight, setDrawerHeight] = useState(400);
  // 记录拖拽开始时的鼠标Y坐标和抽屉初始高度
  const dragStartInfo = useRef({ startY: 0, startHeight: 0 });
  // 标记是否处于拖拽状态
  const isDragging = useRef(false);

  // 鼠标按下时触发,初始化拖拽信息
  const handleDragStart = (e) => {
    isDragging.current = true;
    dragStartInfo.current = {
      startY: e.clientY,
      startHeight: drawerHeight
    };
    // 阻止默认行为,避免页面滚动干扰拖拽
    e.preventDefault();
  };

  return (
    <div className="drawer-container" style={{ height: `${drawerHeight}px` }}>
      {/* 顶部拖拽手柄 */}
      <div 
        className="drawer-drag-handle"
        onMouseDown={handleDragStart}
      >
        <span>拖拽调整高度</span>
      </div>
      {/* 抽屉内容区域 */}
      <div className="drawer-content">
        这里是抽屉的内容区域...
      </div>
    </div>
  );
};

export default DraggableDrawer;

2. 全局监听拖拽过程

因为拖拽时鼠标可能移出抽屉区域,所以要在window上监听mousemove和mouseup事件,确保拖拽过程连贯:

useEffect(() => {
  const handleDragMove = (e) => {
    if (!isDragging.current) return;

    // 计算鼠标移动距离:向上拖增加高度,向下拖减少高度
    const deltaY = dragStartInfo.current.startY - e.clientY;
    // 限制高度范围,避免抽屉过小或过大
    const newHeight = Math.max(200, Math.min(800, dragStartInfo.current.startHeight + deltaY));
    
    setDrawerHeight(newHeight);
  };

  const handleDragEnd = () => {
    isDragging.current = false;
  };

  // 添加全局事件监听
  window.addEventListener('mousemove', handleDragMove);
  window.addEventListener('mouseup', handleDragEnd);

  // 组件卸载时移除监听,避免内存泄漏
  return () => {
    window.removeEventListener('mousemove', handleDragMove);
    window.removeEventListener('mouseup', handleDragEnd);
  };
}, [drawerHeight]);

3. 样式优化(可选但建议)

给拖拽手柄添加明显样式,让用户清晰感知可交互:

.drawer-container {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  border-top: 1px solid #eee;
  box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
  overflow: hidden;
}

.drawer-drag-handle {
  height: 30px;
  background: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: ns-resize; /* 鼠标显示上下箭头样式 */
  user-select: none; /* 防止拖拽时选中文本 */
}

.drawer-content {
  height: calc(100% - 30px);
  overflow-y: auto;
  padding: 16px;
}

方案优势

  • 完全遵循React数据驱动视图原则:所有高度变化都通过更新state触发组件重渲染,没有直接操作DOM样式。
  • 无第三方依赖:只用React原生Hooks实现,不需要引入jQuery或其他拖拽库。
  • 体验完善:通过全局事件监听保证拖拽连贯性,添加高度边界限制避免异常情况,组件卸载时清理事件防止内存泄漏。

如果是类组件写法,逻辑完全一致:把状态存在this.state中,事件处理函数写为类方法,在componentDidMount添加全局监听,componentWillUnmount移除监听即可。

内容的提问来源于stack exchange,提问作者CarCarlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:49:24