隐藏在向下滚动+固定进度条上的粘性标题

时间:2019-06-09 04:38:42

标签: javascript css

尝试创建标题和进度条,如下所示: https://blog.fullstory.com/cross-functional-collaboration/

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

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

代码段:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

const cors = require('cors')({ origin: true });
const moment = require('moment');

admin.initializeApp();

exports.sendDailyNotifications = functions.https.onRequest((request, response) => {

    cors(request, response, () => {

       const now = moment();
       const dateFormatted = now.format('DDMMYYYY');

       admin.firestore()
       .collection("userCollection").where("birthDate", "==", dateFormatted)
       .get()
       .then(function(querySnapshot) {

           const promises = []; 

           querySnapshot.forEach(doc => {

               const tokenId = doc.data().tokenId;
               const notificationContent = {
                 notification: {
                    title: "...",
                    body: "...",
                    icon: "default",
                    sound : "default"
                 }
              };

              promises
              .push(admin.messaging().sendToDevice(tokenId, notificationContent));      

          });
          return Promise.all(promises);
       })
       .then(results => {
            response.send(data)
       })
       .catch(error => {
          console.log(error)
          response.status(500).send(error)
       });

    });

});
// 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;
}

我正在尝试使其正常工作。 有任何想法吗?

3 个答案:

答案 0 :(得分:1)

您可以使用纯JavaScript来实现,不需要jQuery。

您可以填充内容并具有任意高度。使用JavaScript,您可以计算顶部元素的高度。

由于进度条不在top之外,因此您可以将top移到-Height并在视图中保留进度条。

var lastpos = 0;

document.addEventListener('scroll',function(){
		
	let pos = document.documentElement.scrollTop || document.body.scrollTop;
	let windowHeight = document.documentElement.clientHeight || window.innerHeight;
	let sHeight = document.documentElement.scrollHeight;
	let pWidth = ((pos/(sHeight-windowHeight))*100);
		
	let top = document.getElementById('top');
	let percent = document.getElementById('percent');
		
	if (pos>top.clientHeight && (pos>=sHeight-windowHeight-100 || lastpos<=pos)){
		top.style.top = (-top.clientHeight)+'px';
	}else{
		top.style.top = 0;
	}
		
	percent.style.width = Math.ceil(pWidth)+'%';

    lastpos = pos;
		
},true);
*{ padding: 0; margin: 0;}

#top{
	position: fixed;
	top: 0;
	width: 100%;
	background-color: #2E7CFF;
	height: inherit;
}

.progress{
	position: relative;
	width: 100%;
}

#percent{
	position: absolute;
	display: block;
	bottom: -3px;
	height: 3px;
	width: 0;
	background-color: #FF2E7F;
}

#top{
	transition: all ease-in-out 0.8s;
}

#percent{
	transition: all ease-in-out 0.1s;
}

.content{
    height: 4000px;
    padding-top: 100px;
}
<div id="top">
	<div>
		Some Content for header
		<br>
		another line
	</div>
	<div class="progress">
		<div id="percent"></div>
	</div>
</div>

<div class="content">Content Inside the Page</div>

答案 1 :(得分:1)

我不得不从头开始,删除了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 more scroll events when the pages reached the bottom, so we fix it
             setTimeout(smartScroll, 333); // trigger one more smartScroll event after 333ms when no more event come in

        } // end of smartScroll

        window.addEventListener('scroll', smartScroll);
        smartScroll(); // init the progress bar on page refresh

    </script>
    </html>

答案 2 :(得分:1)

基于@ICE的答案,这可以跨浏览器工作:

    var lastpos = 0;
    document.addEventListener('scroll',function() {
      let pos = document.documentElement.scrollTop || document.body.scrollTop; // use window.pageYOffset?
      let windowHeight = document.documentElement.clientHeight || window.innerHeight;
      let sHeight = document.documentElement.scrollHeight;
      let maxScrollHeight = sHeight-windowHeight;
      if (pos >= maxScrollHeight) {
        pos = maxScrollHeight;
      }
      let pWidth = ((pos/maxScrollHeight)*100);

      let top = document.getElementById('top');
      let percent = document.getElementById('percent');

      if (pos>top.clientHeight && lastpos<=pos) {
        top.style.top = (-top.clientHeight)+'px';
      } else {
        top.style.top = 0;
      }
      percent.style.width = Math.ceil(pWidth)+'%';
      lastpos = pos;

    },true);