首页 > 解决方案 > 在多个元素中将进度条显示为滚动

问题描述

我正在尝试创建一个用户滚动查看帖子的帖子页面。有多个带有侧边栏的帖子,所以我想显示一个进度条来指示文章位置。当我导航到第一个元素时,我为此编写的代码运行良好,但不适用于之后的元素。

这是代码。fiddle 我试图在这里设置一个我想在侧边栏参考链接中实现类似的东西

var contentSections = $('.single_page_post');
jQuery(window).on('scroll', function () {
    updateNavigation();
});
function updateNavigation() {
    contentSections.each(function () {
        $this = $(this);
        var theID = $this.attr("id");
        if (($this.offset().top - $(window).height() / 2 < $(window).scrollTop()) && ($this.offset().top + $this.height() - $(window).height() / 2 > $(window).scrollTop())) {
            var s = $(window).scrollTop(),
            d = $this.height(),
            c = $this.offset().top;
            var scrollPercent = (s / (d - c)) * 100;
            var progressheight = 100-scrollPercent;
            $("a[href='#" + theID + "']").prev().css({'height' : progressheight+"%", 'display' : 'block'});
            $("a[href='#" + theID + "']").parents('.post_page_sidebar').addClass("current");
        } else {
            $("a[href='#" + theID + "']").prev().css({'display' : 'none'});
            $("a[href='#" + theID + "']").parents('.post_page_sidebar').removeClass("current");
        }
    });
}
.content_area {
  width: 60%;
  float:left;
}
.post_page_sidebar {
  position: relative;
}
.post_progress {

    position: absolute;
    width: 5px;
    background: red;
    bottom:0px;
}
a {

    padding: 10px 10px 10px 7px;
    display: inline-block;

}
li {

    list-style: none;

}
.sidebar {
  width: 30%;
  position: fixed;
  top: 0px;
}
.single_page_post {
  height: 500px;
  border: 2px solid #e2e2e2;
  margin-top: 5px;
  margin-left:200px;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sidebar">
  <ul>
   <li id="sidebar_post_267" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_267">Dummy Post 4</a>
   </li>
   <li id="sidebar_post_263" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_263">Dummy Post 3</a>
   </li>
   <li id="sidebar_post_261" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_261">Dummy Post 2</a>
   </li>
   <li id="sidebar_post_131" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_131">Test Post</a>
   </li>
</ul>
</div>
<div class="content_area">
  <div class="single_page_post" id="post_section_267">
    
  </div>
  <div class="single_page_post" id="post_section_263">
    
  </div>
  <div class="single_page_post" id="post_section_261">
    
  </div>
  <div class="single_page_post" id="post_section_131">
    
  </div>
</div>

标签: javascriptjqueryscroll

解决方案


你的代码有两个问题。第一个是,从逻辑上讲,您不想减去$this.offset().top$this.height()而是想$(window).scrollTop()给您:

var scrollPercent = ((s-c) / (d)) * 100;

第二个是您切换哪篇文章是当前可见文章的逻辑是复杂且错误的。您发布的声明“为时过早”切换了活动文章,因此返回的内容很长,即“用户阅读了这篇文章的 -30%”。检查每个项目是否:

$this.offset().top - $(window).scrollTop() < 0

确定它是否完全在视口中。

这两个更改为您提供了以下代码段:

var contentSections = $('.single_page_post');
jQuery(window).on('scroll', function () {
    updateNavigation();
});
function updateNavigation() {
    contentSections.each(function () {
        $this = $(this);
        var theID = $this.attr("id");
        if ($this.offset().top - $(window).scrollTop() < 0) {
            var s = $(window).scrollTop()-13,
            d = $this.outerHeight(),
            c = $this.offset().top;
            var scrollPercent = ((s-c) / (d)) * 100;
            var progressheight = 100-scrollPercent;
            $("a[href='#" + theID + "']").prev().css({'height' : progressheight+"%", 'display' : 'block'});
            $("a[href='#" + theID + "']").parents('.post_page_sidebar').addClass("current");
        } else {
            $("a[href='#" + theID + "']").prev().css({'display' : 'none'});
            $("a[href='#" + theID + "']").parents('.post_page_sidebar').removeClass("current");
        }
    });
} 
.content_area {
  width: 60%;
  float:left;
}
.post_page_sidebar {
  position: relative;
}
.post_progress {

    position: absolute;
    width: 5px;
    background: red;
    bottom:0px;
}
a {

    padding: 10px 10px 10px 7px;
    display: inline-block;

}
li {

    list-style: none;

}
.sidebar {
  width: 30%;
  position: fixed;
  top: 0px;
}
.single_page_post {
  height: 500px;
  border: 2px solid #e2e2e2;
  margin-top: 5px;
  margin-left:200px;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sidebar">
  <ul>
   <li id="sidebar_post_267" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_267">Dummy Post 4</a>
   </li>
   <li id="sidebar_post_263" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_263">Dummy Post 3</a>
   </li>
   <li id="sidebar_post_261" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_261">Dummy Post 2</a>
   </li>
   <li id="sidebar_post_131" class="post_page_sidebar">
      <div class="post_progress"></div>
      <a href="#post_section_131">Test Post</a>
   </li>
</ul>
</div>
<div class="content_area">
  <div class="single_page_post" id="post_section_267">
    
  </div>
  <div class="single_page_post" id="post_section_263">
    
  </div>
  <div class="single_page_post" id="post_section_261">
    
  </div>
  <div class="single_page_post" id="post_section_131">
    
  </div>
</div>


推荐阅读