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

React自定义可调整大小Div遇问题:缩至下限方向错误

自定义可调整大小组件的最小尺寸问题解决

我正在不依赖第三方库的情况下自定义实现可调整大小组件,点击左上角调整手柄时isDragging会被设为true,随后handleMouseMove会调整Div的尺寸和位置。但遇到了最小尺寸的问题:当宽度从11px缩至10px时,尺寸会更新,但位置不会更新(因newWidth等于10),导致Div从右侧边框调整尺寸,而预期应从左侧调整。

尝试把判断条件从if (newWidth > 10)替换为if (dimension.width > 10),又导致从10px扩至11px时,Div从右侧边框展开。不知道该如何解决,是否需要换一种方案从头构建?

原代码如下:

useEffect(() => {
    const handleMouseMove = (event : React.MouseEvent<HTMLDivElement> ) : void => {
      if (isDragging) {
        const deltaX: number = startCo.x - event.clientX;
        const deltaY: number = startCo.y - event.clientY;
        const newWidth: number = Math.max(10,dimension.width + deltaX);
        const newHeight: number = Math.max(10, dimension.height + deltaY);
        setDimension({ width: newWidth, height: newHeight });
        if (newWidth > 10) {
          const newPosX: number = position.x - deltaX;
          const newPosY: number = position.y - deltaY;
          setPosition({x: newPosX, y: newPosY});
        }
        setStartCo({ x: event.clientX, y: event.clientY });
        console.log(deltaX)

      }
...

核心问题是你当前的逻辑把尺寸限制和位置更新的判断绑定在了一起,导致边界情况出错。可以换个思路:不管尺寸是否达到最小值,先计算「理论上应该更新的位置」,再结合最小尺寸的限制调整最终的尺寸和位置。

修改后的逻辑步骤

  1. 先计算无限制情况下的新尺寸和新位置,确保位置逻辑完全跟随鼠标移动
  2. 对尺寸应用最小限制,位置则保持原本的计算结果(即使尺寸被限制,位置仍要跟着鼠标拖拽逻辑走)

修改后的handleMouseMove代码

useEffect(() => {
  const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>): void => {
    if (isDragging) {
      const deltaX: number = startCo.x - event.clientX;
      const deltaY: number = startCo.y - event.clientY;

      // 先计算无任何限制的尺寸和位置
      const unrestrictedWidth = dimension.width + deltaX;
      const unrestrictedHeight = dimension.height + deltaY;
      const unrestrictedPosX = position.x - deltaX;
      const unrestrictedPosY = position.y - deltaY;

      // 应用最小宽度限制,位置保持计算值
      const newWidth = Math.max(10, unrestrictedWidth);
      // 应用最小高度限制,位置保持计算值
      const newHeight = Math.max(10, unrestrictedHeight);

      setDimension({ width: newWidth, height: newHeight });
      setPosition({ x: unrestrictedPosX, y: unrestrictedPosY });
      setStartCo({ x: event.clientX, y: event.clientY });
    }
  };

  // 补充事件监听与清理逻辑
  window.addEventListener('mousemove', handleMouseMove);
  return () => window.removeEventListener('mousemove', handleMouseMove);
}, [isDragging, dimension, position, startCo]);

为什么这样可行?

  • 缩小到10px时,位置仍按照鼠标移动的距离更新,左上角手柄始终跟随鼠标,视觉上就是从左侧调整尺寸
  • 从10px开始放大时,尺寸和位置的计算是连续的,不会出现跳变,保证从左侧正常展开
  • 不需要从头重构组件,只需要解开尺寸限制和位置更新的绑定关系即可

内容的提问来源于stack exchange,提问作者MInH THiỆn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:17:12