如何实现基于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
相关产品推荐
相关产品推荐

