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

如何实现基于Django Model的无限循环横向图片滚动画廊?

实现Django生成图片的横向无限循环滚动组件

当前的横向滚动仅静态展示列表,要实现无限循环,核心思路是复制列表内容,让滚动到边界时能无缝衔接,下面分两种场景给出具体实现方案:

方案一:自动无限滚动(纯CSS+模板复制)

适合无需用户手动交互、自动滚动展示的场景。

1. 修改Django模板,复制列表内容

在原有列表后再复制一份,让容器内内容为原列表的两倍:

<div class="top-display snaps-inline">
  {% for top in clothes %}
    <div class="top-wrapper">
      <img class="top-image" src="{{ top.image.url }}">
    </div>
  {% endfor %}
  <!-- 复制原列表,实现无缝衔接 -->
  {% for top in clothes %}
    <div class="top-wrapper">
      <img class="top-image" src="{{ top.image.url }}">
    </div>
  {% endfor %}
</div>

2. 添加CSS滚动动画

在原有样式基础上新增动画规则,支持hover暂停:

.top-display {
  /* 保留原有样式 */
  position: relative;
  display: grid;
  gap: 5rem;
  grid-auto-flow: column;
  grid-auto-columns: 17%;
  padding: 0 var(--_spacer) var(--_spacer);
  overflow-x: hidden;
  overflow-y: hidden;
  overscroll-behavior-inline: contain;
  white-space: nowrap;
  /* 新增自动滚动动画 */
  animation: scroll 20s linear infinite;
}

/* 定义滚动逻辑:滚动过原列表宽度后重置位置 */
@keyframes scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

/* 鼠标悬停时暂停滚动 */
.top-display:hover {
  animation-play-state: paused;
}

方案二:手动滑动无限循环(JS+模板复制)

适合需要用户手动左右滑动、边界无缝跳转的场景。

1. 修改Django模板,复制前后内容

在原列表前复制反转列表、后复制原列表,让容器内内容为原列表的三倍:

<div class="top-display snaps-inline" id="infinite-scroll-container">
  <!-- 复制反转列表到前面,实现开头滑向末尾的无缝衔接 -->
  {% for top in clothes reversed %}
    <div class="top-wrapper">
      <img class="top-image" src="{{ top.image.url }}">
    </div>
  {% endfor %}
  <!-- 原列表 -->
  {% for top in clothes %}
    <div class="top-wrapper">
      <img class="top-image" src="{{ top.image.url }}">
    </div>
  {% endfor %}
  <!-- 复制原列表到后面,实现末尾滑向开头的无缝衔接 -->
  {% for top in clothes %}
    <div class="top-wrapper">
      <img class="top-image" src="{{ top.image.url }}">
    </div>
  {% endfor %}
</div>

2. 添加JS逻辑处理滚动跳转

监听滚动事件,当到达边界时瞬间跳转到中间原列表位置:

const container = document.getElementById('infinite-scroll-container');
// 获取单个列表项的宽度(包含间距)
const item = container.querySelector('.top-wrapper');
const itemWidth = item.offsetWidth + parseInt(getComputedStyle(container).gap);
// 原列表总宽度,用于初始定位和边界跳转
const originalListWidth = itemWidth * {{ clothes|length }};

// 初始滚动到中间原列表的起始位置
container.scrollLeft = originalListWidth;

// 监听滚动,处理边界跳转
container.addEventListener('scroll', () => {
  // 滚动到最左侧时,跳转到原列表起始位置
  if (container.scrollLeft <= 0) {
    container.scrollLeft = originalListWidth;
  }
  // 滚动到最右侧时,跳转到原列表起始位置
  if (container.scrollLeft >= container.scrollWidth - container.offsetWidth) {
    container.scrollLeft = originalListWidth;
  }
});

3. 保留原有CSS样式

无需修改原有CSS,保持横向滚动的基础样式即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:07:24