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

横向列表滚动优化:触底停止+按元素宽度滚动需求

解决方案

一、滚动至最右端时停止向右滚动

要实现滚动到最右端后停止,核心是判断容器是否已经到达滚动边界:

  • scrollLeft:容器已滚动的水平距离
  • clientWidth:容器可见区域的宽度
  • scrollWidth:容器内容的总宽度(含不可见部分)

当scrollLeft + clientWidth >= scrollWidth时,说明已滚动到最右端,此时不再执行向右滚动操作。

二、每次滚动距离改为下一个元素的宽度

通过遍历列表项,找到当前可见区域外的下一个元素,计算该元素的偏移量来确定滚动距离,而非固定像素值。

修改后的完整代码

JavaScript 代码

document.addEventListener('DOMContentLoaded', function() {
  const container = document.querySelector('.scrollable-list');
  const btnRight = document.querySelector('.scroll-btn.right');
  const btnLeft = document.querySelector('.scroll-btn.left');
  const listItems = Array.from(container.querySelectorAll('li'));

  btnRight.addEventListener('click', function() {
    // 判断是否已到最右端
    if (container.scrollLeft + container.clientWidth >= container.scrollWidth) {
      return;
    }
    
    // 找到第一个超出可见区域右侧的元素
    let nextItem = null;
    const containerRect = container.getBoundingClientRect();
    for (const item of listItems) {
      const itemRect = item.getBoundingClientRect();
      if (itemRect.left > containerRect.right) {
        nextItem = item;
        break;
      }
    }
    
    if (nextItem) {
      // 计算滚动距离:元素左侧偏移量 - 当前滚动距离
      const scrollDistance = nextItem.offsetLeft - container.scrollLeft;
      container.scrollBy({
        left: scrollDistance,
        behavior: 'smooth'
      });
    } else {
      // 边界处理:滚动到最右端
      container.scrollTo({
        left: container.scrollWidth - container.clientWidth,
        behavior: 'smooth'
      });
    }
  });

  btnLeft.addEventListener('click', function() {
    // 判断是否已到最左端
    if (container.scrollLeft <= 0) {
      return;
    }
    
    // 找到第一个超出可见区域左侧的元素
    let prevItem = null;
    const containerRect = container.getBoundingClientRect();
    for (const item of [...listItems].reverse()) {
      const itemRect = item.getBoundingClientRect();
      if (itemRect.right < containerRect.left) {
        prevItem = item;
        break;
      }
    }
    
    if (prevItem) {
      // 计算滚动距离:当前滚动距离 - 元素右侧偏移量
      const scrollDistance = container.scrollLeft - (prevItem.offsetLeft + prevItem.offsetWidth);
      container.scrollBy({
        left: -scrollDistance,
        behavior: 'smooth'
      });
    } else {
      // 边界处理:滚动到最左端
      container.scrollTo({
        left: 0,
        behavior: 'smooth'
      });
    }
  });
});

CSS 代码(保持原代码不变)

.container {
  display: flex;
  align-items: center;
  overflow: hidden;
}

.scrollable-list {
  overflow-x: auto;
  white-space: nowrap;
}

.scrollable-list ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
}

.scrollable-list li {
  padding: 10px;
  display: inline-block;
}

.scroll-btn {
  cursor: pointer;
  background: #ddd;
  border: none;
  padding: 10px 20px;
}

.scroll-btn:hover {
  background: #ccc;
}

HTML 代码(保持原代码不变)

<div class="container">
  <button class="scroll-btn left">&lt;</button>
  <div class="scrollable-list">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
      <li>Item 7</li>
      <li>Item 8</li>
      <li>Item 9</li>
      <!-- Add more list items as needed -->
    </ul>
  </div>
  <button class="scroll-btn right">&gt;</button>
</div>

关键逻辑说明

  1. 边界判断:

    • 向右滚动时,通过scrollLeft + clientWidth >= scrollWidth确认是否到达最右端,满足则终止滚动。
    • 向左滚动时,通过scrollLeft <= 0确认是否到达最左端,满足则终止滚动。
  2. 动态滚动距离计算:

    • 向右滚动:遍历列表项,找到第一个完全在可见区域右侧的元素,计算该元素左侧到容器左侧的偏移量与当前滚动距离的差值,作为滚动距离。
    • 向左滚动:反向遍历列表项,找到第一个完全在可见区域左侧的元素,计算当前滚动距离与该元素右侧偏移量的差值,作为滚动距离。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:50:17