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

如何实现两个相邻div垂直同步滚动、水平一滚一固定?

如何实现两个div垂直同步滚动但水平滚动独立?

当然可以实现这个需求!我来给你拆解一下具体的实现思路和代码示例,刚好匹配你说的「描述区固定、项目区可水平滚动」的场景。

核心思路

  • 监听两个div的scroll事件,当其中一个发生垂直滚动时,同步更新另一个的scrollTop值;
  • 对于水平滚动,只保留各自的scrollLeft值,不做同步操作,这样就能实现水平滚动独立的效果。

具体实现代码

HTML结构

先搭建基础的面板结构,区分描述区和项目区:

<div class="container">
  <div class="description-panel">
    <!-- 描述区内容,固定宽度,禁止水平滚动 -->
    <p>项目1描述:这是第一个项目的详细说明</p>
    <p>项目2描述:这是第二个项目的详细说明</p>
    <p>项目3描述:这是第三个项目的详细说明</p>
    <p>项目4描述:这是第四个项目的详细说明</p>
    <!-- 更多描述内容... -->
  </div>
  <div class="items-panel">
    <!-- 项目区内容,宽度超出容器,支持水平滚动 -->
    <div class="wide-item-row">项目1 项目2 项目3 项目4 项目5 项目6 项目7 项目8 项目9 项目10</div>
    <div class="wide-item-row">项目11 项目12 项目13 项目14 项目15 项目16 项目17 项目18 项目19 项目20</div>
    <!-- 更多项目行内容... -->
  </div>
</div>

CSS样式

设置容器和面板的基础样式,确保描述区固定宽度、禁止水平滚动,项目区支持双向滚动:

.container {
  display: flex;
  height: 300px; /* 固定容器可视高度 */
  overflow: hidden;
  border: 1px solid #ddd;
}

.description-panel {
  width: 220px;
  background-color: #f5f5f5;
  overflow-y: auto;
  overflow-x: hidden; /* 锁定水平滚动 */
  padding: 10px;
}

.items-panel {
  flex: 1;
  background-color: #fff;
  overflow: auto; /* 同时支持垂直+水平滚动 */
  padding: 10px;
}

.wide-item-row {
  width: 1000px; /* 模拟超长内容,触发水平滚动 */
  line-height: 2.5;
}

JavaScript逻辑

这是实现同步滚动的核心,通过监听滚动事件来同步垂直位置:

const descPanel = document.querySelector('.description-panel');
const itemsPanel = document.querySelector('.items-panel');

// 监听描述区滚动,同步项目区的垂直滚动位置
descPanel.addEventListener('scroll', (e) => {
  itemsPanel.scrollTop = e.target.scrollTop;
});

// 监听项目区滚动,同步描述区的垂直滚动位置,水平滚动保持独立
itemsPanel.addEventListener('scroll', (e) => {
  descPanel.scrollTop = e.target.scrollTop;
  // 这里不修改scrollLeft,所以项目区的水平滚动不受影响
});

优化建议

如果你的面板内容非常长,滚动事件会频繁触发,可能导致性能问题。可以给滚动事件加个防抖处理:

// 防抖函数
function debounce(func, delay = 15) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, args), delay);
  };
}

// 使用防抖包裹滚动监听
descPanel.addEventListener('scroll', debounce((e) => {
  itemsPanel.scrollTop = e.target.scrollTop;
}));

itemsPanel.addEventListener('scroll', debounce((e) => {
  descPanel.scrollTop = e.target.scrollTop;
}));

这样就能完美实现你想要的效果:垂直方向两个面板同步滚动,项目区可以自由水平滚动,描述区始终保持固定不水平滚动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:05:33