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

如何实现页面滚动时右侧目录左侧红色边框的动画效果

功能实现修正方案

原有代码存在以下问题:

  • runOnScroll函数未实现获取元素距离视口位置的逻辑
  • 错误调用DOM节点不存在的runOnScroll方法
  • querySelector选中逻辑错误,.rightwrap li下不存在同选择器子元素
  • querySelectorAll返回的是节点列表,不能直接调用classList方法

实现逻辑说明

用两个伪元素分别做目录项左侧的灰色背景条和红色动态进度条,滚动时计算每个内容区块进入视口的占比,动态设置红色进度条的高度,同时给处于激活状态的目录项加状态标识。

修正后完整代码

HTML代码

<!-- 补充缺失的Row1结构 -->
<section class="dashlineWrap">
  <div class="vc_row h-500" id="tableofcontent-1">
    <h4>Row 1</h4>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </div>
</section>
<section class="dashlineWrap">
  <div class="vc_row h-500" id="tableofcontent-2">
    <h4>Row 2</h4>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </div>
</section>
<section class="dashlineWrap">
  <div class="vc_row h-500" id="tableofcontent-3">
    <h4>Row 3</h4>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </div>
</section>
<div class="rightwrap">
  <ul>
    <li class="active"><a href="#tableofcontent-1">Row 1</a></li>
    <li><a href="#tableofcontent-2">Row 2</a></li>
    <li><a href="#tableofcontent-3">Row 3</a></li>
  </ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

CSS代码

.mainWrapper {
  display: flex;
}
.leftWrap {
  width: 600px;
  margin: auto;
  border: 1px solid #222;
}
.rightwrap {
  position: fixed;
  top: 0;
  right: 50px;
}
.h-500 {
  height: 650px
}
.dashlineWrap {
  background-color: #f9f9f9;
}
.vc_row {
  height: 500px;
}
.rightwrap ul li {
  position: relative;
  list-style: none;
  padding-bottom: 15px;
}
/* 红色动态进度条 */
.rightwrap ul li::before {
  content: '';
  width: 2px;
  height: var(--active-height, 0);
  background-color: red;
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  transition: height 0.2s ease;
}
/* 灰色背景条 */
.rightwrap ul li::after {
  content: '';
  width: 2px;
  height: 100%;
  background-color: #E5E5E5;
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}
.rightwrap ul li a {
  padding-left: 15px;
  display: flex;
}

JS代码

// 获取所有内容区块和对应的目录项
const contentSections = document.querySelectorAll('.vc_row');
const catalogItems = document.querySelectorAll('.rightwrap li');

window.addEventListener("scroll", () => {
  // 取视口中线位置作为判断激活的基准
  const viewportMiddle = window.scrollY + window.innerHeight / 2;
  catalogItems.forEach((item, index) => {
    const currentSection = contentSections[index];
    const sectionTop = currentSection.offsetTop;
    const sectionBottom = sectionTop + currentSection.offsetHeight;
    let progress = 0;
    // 计算当前内容区块的浏览进度
    if (viewportMiddle > sectionTop && viewportMiddle < sectionBottom) {
      progress = (viewportMiddle - sectionTop) / currentSection.offsetHeight;
      item.classList.add('active');
    } else if (viewportMiddle >= sectionBottom) {
      progress = 1;
      item.classList.add('active');
    } else {
      item.classList.remove('active');
    }
    // 动态设置红色进度条高度
    item.style.setProperty('--active-height', `${progress * 100}%`);
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:21:01