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

如何实现文本无缝循环滚动?附现有代码求解决方案

实现文本无缝循环滚动的方案

核心思路

  • 复制一份滚动内容,让原内容与复制内容首尾相连,形成连续的“循环体”
  • 当滚动容器向上滚动完原内容的高度时,瞬间将容器位置重置到初始状态,由于复制内容和原内容完全一致,视觉上不会出现空白间隙
  • 用JavaScript控制滚动逻辑,适配动态内容高度,比纯CSS方案更灵活

修改后的完整代码

HTML

<div id="jobs_container">
  <div id="jobs_header">
    <div id="jobs_header_left"></div>
    <div id="jobs_header_center">Center text</div>
    <div id="jobs_header_right"></div>
  </div>
  <div id="jobs_content">
    <div id="jobs_listOfEvents">
      line1<hr>
      line2<hr>
      line3<hr>
      line4<hr>
      line5<hr>
      line6<hr>
      line7<hr>
      line8<hr>
      line9<hr>
    </div>
    <!-- 复制一份内容用于无缝衔接 -->
    <div id="jobs_listOfEvents_copy"></div>
  </div>
</div>

CSS

#jobs_container {
  background: transparent;
  width: 600px;
  height: 300px;
  border: 3px solid #e4e4e4;
  border-radius: 12px;
  border-style: dashed;
  padding: 1px;
  font-size: 12px;
}

#jobs_header {
  display: flex;
  justify-content: space-between;
  height: 25px;
  background-color: #e4e4e4;
  border-radius: 12px 12px 0 0;
  padding: 1rem;
}
#jobs_header_left {
  display: flex;
  align-items: center;
}
#jobs_header_left > span {
  padding-right: 4px;
  cursor: pointer;
  color: #0048FF;
}
#jobs_header_center {
  text-align: center;
  font: 20px Verdana;
  color: darkblue;
}

#jobs_header_right {
  display: flex;
  align-items: center;
}
#jobs_today {
  margin-inline: 5px;
  cursor: pointer;
  color: #0048FF;
}
#jobs_nextButton {
  background: transparent;
  border: none;
  padding: 0px 3px;
  cursor: pointer;
}

#jobs_prevButton {
  background: transparent;
  border: none;
  transform: scaleX(-1);
  padding: 0px 3px;
  cursor: pointer;
}

#jobs_content {
  font-family: calibre;
  margin-left: 10px;
  margin-top: 10px;
  position: relative;
  overflow: hidden; /* 只显示容器范围内的内容 */
  max-height: 220px; /* 减去header高度,避免超出容器 */
  text-align: justify;
}

#jobs_listOfEvents, #jobs_listOfEvents_copy {
  position: relative;
}

JavaScript

const originalList = document.getElementById('jobs_listOfEvents');
const copyList = document.getElementById('jobs_listOfEvents_copy');
// 复制原内容到副本
copyList.innerHTML = originalList.innerHTML;

const contentContainer = document.getElementById('jobs_content');
const itemHeight = originalList.offsetHeight;

// 创建滚动动画
function startScroll() {
  // 重置初始位置
  originalList.style.top = '0px';
  copyList.style.top = `${itemHeight}px`;
  
  let scrollPosition = 0;
  const scrollSpeed = 0.5; // 滚动速度,数值越小越慢
  let requestId;
  
  function animateScroll() {
    scrollPosition += scrollSpeed;
    originalList.style.top = `-${scrollPosition}px`;
    copyList.style.top = `${itemHeight - scrollPosition}px`;
    
    // 当滚动完原内容高度时,重置位置实现无缝衔接
    if (scrollPosition >= itemHeight) {
      scrollPosition = 0;
    }
    
    requestId = requestAnimationFrame(animateScroll);
  }
  
  requestId = requestAnimationFrame(animateScroll);
  
  // 鼠标悬停暂停滚动,离开继续
  contentContainer.addEventListener('mouseenter', () => {
    cancelAnimationFrame(requestId);
  });
  
  contentContainer.addEventListener('mouseleave', () => {
    requestId = requestAnimationFrame(animateScroll);
  });
}

// 页面加载完成后启动滚动
window.addEventListener('load', startScroll);

关键逻辑说明

  1. 内容复制:将原滚动内容复制一份,放在原内容下方,形成连续的内容流
  2. 滚动控制:用requestAnimationFrame实现平滑向上滚动,同步控制原内容和副本的位置
  3. 无缝重置:当滚动距离等于原内容高度时,立即重置滚动位置,此时副本顶部刚好衔接原内容底部,视觉上无间隙
  4. 交互优化:添加鼠标悬停暂停滚动的功能,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:05:33