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

如何修复React Resizable宽度增加时滚动条右移问题?

修复React Resizable宽度增加时的滚动偏移问题

使用react-resizable的ResizableBox组件实现横向可拉伸容器时,遇到以下问题:拉伸容器宽度时,内部滚动元素无法保持原位,滚动条会自动向右偏移,需要修复该滚动异常。

原React组件代码

<reactResizable.ResizableBox
  className="box"
  width={200}
  height={200}
  axis="x"
  resizeHandles={["e"]}
>
  <div className="inner">
    {Array.from(generateSequence(1, 6)).map((e) => {
      return (
        <div>
          <span className="text">BLOCK {e}</span>
        </div>
      );
    })}
  </div>
</reactResizable.ResizableBox>

原CSS代码

.box {
  background: white;
  overflow: auto hidden;
}

.box .react-resizable-handle-e {
  height: 100%;
  background-color: red;
  transform: rotate(0);
  top: 0;
}

.inner {
  height: 200px;
  color: black;
  display: flex;
  overflow-x: overlay;
}

.inner > div {
  min-width: 150px;
  height: 100px;
  border: 4px solid black;
}

问题原因

  1. 嵌套滚动容器冲突:.box和.inner都设置了横向滚动,容器宽度变化时,浏览器会自动调整内层滚动位置,引发元素偏移。
  2. 浏览器自动滚动调整:容器宽度改变时,浏览器会尝试保持视口内元素的可见性,自动修改scrollLeft值,破坏了元素原位的需求。

修复方案

1. 调整滚动容器层级

将滚动容器统一到ResizableBox本身(.box),去掉.inner的滚动设置,避免嵌套滚动逻辑冲突。

2. 锁定滚动位置

通过ResizableBox的onResize回调,在宽度变化时强制保持原scrollLeft值,阻止浏览器自动调整。

修改后的完整代码

React组件代码
<reactResizable.ResizableBox
  className="box"
  width={200}
  height={200}
  axis="x"
  resizeHandles={["e"]}
  onResize={(e, { element }) => {
    // 记录原滚动位置,在resize完成后强制恢复
    const originalScrollLeft = element.scrollLeft;
    requestAnimationFrame(() => {
      element.scrollLeft = originalScrollLeft;
    });
  }}
>
  <div className="inner">
    {Array.from(generateSequence(1, 6)).map((e) => {
      return (
        <div key={e}>
          <span className="text">BLOCK {e}</span>
        </div>
      );
    })}
  </div>
</reactResizable.ResizableBox>
CSS代码
.box {
  background: white;
  overflow-x: auto; /* 仅开启横向滚动 */
  overflow-y: hidden;
}

.box .react-resizable-handle-e {
  height: 100%;
  background-color: red;
  transform: rotate(0);
  top: 0;
}

.inner {
  height: 200px;
  color: black;
  display: flex;
  /* 移除inner的overflow-x设置,由外层box负责滚动 */
}

.inner > div {
  min-width: 150px;
  height: 100px;
  border: 4px solid black;
}

说明

  • 移除内层.inner的overflow-x,让ResizableBox直接作为滚动容器,避免双重滚动逻辑干扰。
  • 使用requestAnimationFrame确保在resize完成后再设置scrollLeft,覆盖浏览器的自动调整行为,保证内部元素始终保持原位。
  • 给循环生成的元素添加key属性,符合React列表渲染规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:31:12