javascript - jQuery 滚动进度条固定并随滚动条移动

标签 javascript jquery html css

我想实现一个随滚动条移动的进度条。像这样的事情:

Scrollable Progress Bar

我在这里发现了一些功能几乎像这样的东西:

$(document).ready(function(){

  // Anchor arrow click
  // smooth scroll to anchor tag
 $('a[href*="#"]:not([href="#featured"])').click(function() { // Check to see if anchor tag is not carousel's featured link
      if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
        var target = $(this.hash);
        target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
        if (target.length) {
          // Smooth scroll to link section
          $('html, body').animate({
            scrollTop: target.offset().top + 50
          }, 900);
          return false;
        }
      }
    });
    
  //highlight navigation
  $(window).scroll(function() {
    var windowpos = $(window).scrollTop();
    $('nav li a').removeClass('active');
    $('.progress-bar--circle').removeClass('active');

    if (windowpos > $('#top').offset().top) {
      $('nav li a').removeClass('active');
      $('a[href$="#top"]').addClass('active');
    } //windowpos

    if (windowpos > $('#article-1').offset().top) {
      $('nav li a').removeClass('active');
      $('a[href$="#article-1"]').addClass('active');
      $('a[href$="#article-1"] .progress-bar--circle').addClass('active');
    } //windowpos

    if (windowpos > $('#article-2').offset().top) {
      $('nav li a').removeClass('active');
      $('a[href$="#article-2"]').addClass('active');
      $('a[href$="#article-2"] .progress-bar--circle').addClass('active');
    } //windowpos

    if (windowpos > $('#article-3').offset().top) {
      $('nav li a').removeClass('active');
      $('a[href$="#article-3"]').addClass('active');
      $('a[href$="#article-3"] .progress-bar--circle').addClass('active');
    } //windowpos

    if (windowpos > $('#bottom').offset().top) {
      $('nav li a').removeClass('active');
      $('a[href$="#bottom"]').addClass('active');
    } //windowpos

    // Scrollbar progression
        // pixels scrolled from top
    var scrollTop = $(window).scrollTop(),
        // document height
        docHeight = $(document).height(),
        // window height
        winHeight = $(window).height(),
        // percent of document scrolled
        scrollPercent = (scrollTop) / (docHeight - winHeight),
        scrollPercentRounded = Math.round(scrollPercent*100);

    // incement progress bar as user scrolls
    $('.progress-bar--increment').css('height', scrollPercentRounded + '%');
  });

}); // on load
/* Global */
@import url('https://fonts.googleapis.com/css?family=Roboto');

* {
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  font-size: 16px;
  background-color: #2C3E50;
  color: white;
}

/* Navbar - Progress Bar */
.navbar {
  position: fixed;
  top: 5em;
  left: 3em;
  height: 175px;
  z-index: 1;
}

.progress-bar {
    position: absolute;
    top: 0;
    left: 0;
    width: 2px;
    height: 100%;
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 0.5);
}

.progress-bar--increment {
  background-color: #E74C5B;
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 0;
  border-radius: 5px;
}

.progress-bar--circle {
  position: absolute;
  bottom: 5px;
  left: -21px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.8);
  transition: all 0.1s;
}

.progress-bar--circle.active {
  background-color: #E74C5B;
}

.navbar ul {
    padding: 0 1em;
    list-style: none;
}

.navbar ul li {
    position: relative;
    margin-bottom: 1em;
}

.navbar ul li a {
    font-size: 1.2em;
    color: white;
    text-decoration: none;
    transition: all 0.1s;
}

.active {
 color: #E74C5B !important;
}

/* Main */
header {
  width: 100%;
  height: 500px;
}

header h1, article h2, footer h3{
    position: relative;
    top: 50%;
    font-size: 4em;
    text-align: center;
}

article {
    border: 1px solid white;
    width: 100%;
    height: 500px;
}

footer {
    height: 500px;
    width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
    <nav class="navbar">
    <div class="progress-bar"></div>
    <div class="progress-bar--increment"></div>
      <ul>
          <li><a href="#top">Header</a></li>
          <li><a href="#article-1"><span class="progress-bar--circle"></span>Article 1</a></li>
          <li><a href="#article-2"><span class="progress-bar--circle"></span>Article 2</a></li>
          <li><a href="#article-3"><span class="progress-bar--circle"></span>Article 3</a></li>
      </ul>
    </nav>

    <header id="top">
      <h1>Welcome to the top!</h1>
    </header>

    <main>
      <article class="article" id="article-1">
        <h2>Article 1</h2>
      </article>

      <article class="article" id="article-2">
        <h2>Article 2</h2>
      </article>

      <article class="article" id="article-3">
        <h2>Article 3</h2>
      </article>
    </main>

    <footer id="bottom">
      <h3>Welcome to the bottom!</h3>
    </footer>
  </body>

但是,我希望进度条仅填充随着滚动而上下移动的 90px 高度,而不是完全填充进度条。

该视频准确地展示了我在 Dropbox 网站上寻找的内容:
https://www.youtube.com/watch?v=LhcBSUAvCMg

最佳答案

检测在到达内容末尾(或父容器,具体取决于您应用自定义的位置)之前可以滚动的距离。然后,使用该值来确定自定义bar必须滚动的程度;这还需要您了解可以显示多少内容(以像素为单位的高度);使用数学。

这是一个最小的工作示例:

const container = document.querySelector('.container')
const customBar = document.querySelector('.custom-bar')
const getMaxScroll = () => {
  window.scroll(0, container.scrollHeight)
  const scroll = window.pageYOffset
  window.scroll(0, 0)
  return scroll
}

let maxScroll = getMaxScroll()

window.addEventListener('resize', e => {
  maxScroll = getMaxScroll()
})

window.addEventListener('scroll', e => {
  let topValue = 20 + window.pageYOffset + (window.pageYOffset / maxScroll * (window.innerHeight - 130)) // 130 is gotten from the minimum top offset of 20px + the minimum bottom offset of 20px + bar height of 90px
  customBar.style.transform = `translateY(${topValue}px)`
})
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

body {
  background-color: #121212;
}

.container {
  position: relative;
  width: 100%;
  padding: 10px;
  padding-left: 20px;
}

.custom-bar {
  position: absolute;
  top: 0;
  transform: translateY(20px);
  height: 90px;
  width: 2px;
  border-radius: 5px;
  background-color: #FFFFFFCC;
}

.box {
  margin: 10px;
  padding: 20px;
  background-color: #FFFFFF11;
  color: #FFF;
  border-radius: 5px;
}
<div class="container">
  <div class="custom-bar"></div>

  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
  <div class="box">Some box</div>
</div>

关于javascript - jQuery 滚动进度条固定并随滚动条移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60095227/

相关文章:

javascript - 如何将对象传递给AngularJS中的指令?

javascript - jQuery:查找所有可见的必填字段

如果 JavaScript 全局变量意味着从 HTML 元素中提取值,则它无法存储值?

javascript - 如何通过单击屏幕上的表格列来弹出图像

php - laravel 5.6 主机到共享主机上的 cpanel

javascript - PHP 和 jQuery 实时搜索表格问题

javascript - 将 gulp 与请求一起使用

javascript - 如果未选中复选框,如何使表单不提交

javascript - 如何动态添加多个复选框到html表格?

html - 我怎样才能在一个容器中底部对齐多个内联 block div 而不会丢失它们的流量?