首页 > 解决方案 > 向下滚动时隐藏的粘性标题+固定进度条

问题描述

尝试像这样创建标题+进度条: https ://blog.fullstory.com/cross-functional-collaboration/

  1. 需要一个粘性(固定)标题,仅在您向上滚动时显示,在您向下滚动时隐藏。
  2. 标题下方始终固定有一个进度条。当您向上滚动并隐藏蓝色标题时,进度条仍应显示......就像 blog.fullstory.com

https://codepen.io/connecteev/pen/eaqxvj

代码片段:

// Hide Header on scroll down, Show Header on scroll up
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();

$(window).scroll(function(event){
    didScroll = true;
});

setInterval(function() {
    if (didScroll) {
        hasScrolled();
        didScroll = false;
    }
}, 250);

function hasScrolled() {
    var st = $(this).scrollTop();

    // Make sure they scroll more than delta
    if(Math.abs(lastScrollTop - st) <= delta)
        return;

    // If they scrolled down and are past the navbar, add class .nav-up.
    // This is necessary so you never see what is "behind" the navbar.
    if (st > lastScrollTop && st > navbarHeight){
        // Scroll Down
        $('header').removeClass('nav-down').addClass('nav-up');
    } else {
        // Scroll Up
        if(st + $(window).height() < $(document).height()) {
            $('header').removeClass('nav-up').addClass('nav-down');
        }
    }
    lastScrollTop = st;
}
body {
    /* this is to make room for the top nav / header */
    padding-top: 60px;
    overflow-x: hidden;
}

header {
  position: fixed;
  top: 0;
  transition: top 0.8s ease-in-out;
  width: 100%;
  background: blue;
  height: 30px;
}

/* smooth position indicator */
.scroll-progress-bar {
  position: fixed;
  top: 0;
  height: 3px;
  width: 0;
  background: green;
  color: green;
  z-index: 2;
}

.nav-up {
    /* hide the top nav on scroll down */
    top: -300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="tw-z-50">
  <div class="nav-down">
  </div>
  <div class="tw-w-full">
    <div class="scroll-progress-bar"></div>
  </div>
</header>

<div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div><div>This is a test</div>

我正在努力让它发挥作用。有任何想法吗?

标签: javascriptcss

解决方案


我必须从头开始并删除 JQuery 以使其更具可读性,请随意使用此代码或其中的一部分。如果您愿意,您可以随时再次添加 JQuery。

测试在此处实时运行http://testing.2x2p.com/header/

到目前为止,这个概念适用于 Firefox、Safari 和 Chrome。也适用于 iPhone 和 iPad。期待从你们那里听到它在 Android 设备上的作用。

    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Sticky Header with progress-Bar Document</title>
    <style type="text/css">
     #header-wrap {
         position:fixed;
         margin: 0;
         top:0px;
         left:0;
         background-color: blue;
         min-height: 80px;
         width:100%;
         transition: top 666ms;
     }
     #header-content {
         margin: 0;
         padding: 10px;
         background-color: lightblue;
         min-height: 75px;
         box-sizing:border-box;
     }
     #header-progress {
         padding:0px;
         box-sizing:border-box;
         background-color: red;
         height: 5px;
         width: 0%;
         overflow:hidden;
         transition: width 333ms linear;
     }
     #page-content {
         margin-top:80px;
         padding:5px;
         box-sizing:border-box;
         background-color: white;
         width: 100%;
         overflow:scroll;
     }
    </style>
    </head>
    <body>
    <div id="header-wrap">
     <div id="header-content">
       Header bla bla bla..
     </div>
     <div id="header-progress">
      &nbsp;
     </div>
    </div>
    <div id="page-content">
      <h3>Body text 1 </h3>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br><br>
      <h3>Body text 2 </h3>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
       <h3>Body text 3 </h3>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
        This is a test<br>
    </div>
    </body>
    <script language="javascript">
    
        window.prevOffset = 0;
        var smartScrollThrottle = 0;
        const smartScrollHeader = document.getElementById('header-wrap');
        const smartProgressBar = document.getElementById('header-progress');
        const smartScrollPage = document.getElementById('page-content');
        
        var smartScroll = function () {
                    
            if(new Date().getTime()-smartScrollThrottle<200){
                //console.log('smartScrollThrottle is active',smartScrollThrottle);
                return false;
            }
            // reset throttle after minimum of 200ms, allows smartScroll only 5 times per second
            smartScrollThrottle = (new Date()).getTime();
            
            var tempOffset = window.pageYOffset;
            //console.log('tempOffset', tempOffset);
            //console.log('prevOffset', window.prevOffset);
            
            if(tempOffset > (window.prevOffset+25) || tempOffset < 100){
                // hide 75 pixels from the total 80 px 
                smartScrollHeader.style.top = '-75px';
            }
            if(tempOffset < (window.prevOffset-25) || tempOffset < 75){
                // show all 80 pixels
                smartScrollHeader.style.top = '0px';
            }
            
            // update the prevOffset value for the next scroll event
            window.prevOffset = window.pageYOffset;
            //console.log('scrollHeight', smartScrollPage.scrollHeight);
            
            // reuse tempOffset value but now for the progress-bar as percentage
            tempOffset = (tempOffset)/(document.documentElement.scrollHeight-(window.innerHeight || document.documentElement.clientHeight));
            //console.log('Scroll percentage', tempOffset);
            if(tempOffset<0){tempOffset=0;}
            if(tempOffset>1){tempOffset=1;}
            smartProgressBar.style.width = Math.round(tempOffset*100)+"%";

            // Chrome and Firefox do not send scroll events when the pages bottom is reached, so we must fix it
             setTimeout(smartScroll, 333); // just trigger one more smartScroll event 333ms after the last browser event

        } // end of smartScroll
        
        window.addEventListener('scroll', smartScroll);
        smartScroll(); // init the progress bar on page refresh
        
    </script>
    </html>

推荐阅读