【问题标题】:JS Show / hide header on scroll effect - but only after the header has scrolled up and out of windowJS 在滚动效果上显示/隐藏标题 - 但仅在标题向上滚动并移出窗口后
【发布时间】:2020-09-15 13:07:20
【问题描述】:

我有一些简单的 Javascript。向下滚动时,标题消失。向上滚动时出现标题。这一切都很好:

var prevScrollpos = window.pageYOffset;
window.onscroll = function() {
  var currentScrollPos = window.pageYOffset;
  if (prevScrollpos > currentScrollPos) {
    document.querySelector("header").style.top = "0";
  } else {
     document.querySelector("header").style.top = "-7.2rem";
  }
  prevScrollpos = currentScrollPos;
}




header {
    background-color: rgb(255, 255, 255);
    height: 7.2rem;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    transition: top 0.2s ease-in-out;
    z-index: 100;
}

但是,当页面位于窗口的顶部,并且用户向下滚动时,即使滚动了 1px,标题也会消失,在原来的标题处留下很大的空白区域。是否有可能仅在标题从浏览器窗口顶部消失后才开始显示/隐藏滚动脚本?即效果仅在标题的高度滚动后才会生效(以便用户看不到空白区域),即标题不是固定的,而是相对的。它向上滚动并移出窗口。然后效果开始:向下滚动=没有标题/向上滚动=标题固定在窗口顶部。

【问题讨论】:

    标签: javascript jquery css


    【解决方案1】:

    有两种方法可以做到这一点,具体取决于您想要的行为。在这两种情况下,我们都想获取标题元素及其位置:

    var headerDiv = document.querySelector("header");
    var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
    

    这意味着在滚动中,我们可以检查是否通过了header:

        if (window.pageYOffset >= headerBottom)
    

    1:标题正常滚动出视图,向上滚动时固定到顶部

    在这个版本中,当向下滚动时,标题会滚动到视图之外,但是当您开始向上滚动时,它会固定在屏幕顶部。

    完整的工作示例:

    var prevScrollpos = window.pageYOffset;
    
    /* Get the header element and it's position */
    var headerDiv = document.querySelector("header");
    var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
    
    window.onscroll = function() {
      var currentScrollPos = window.pageYOffset;
    
      /* if scrolling down, let it scroll out of view as normal */
      if (prevScrollpos <= currentScrollPos ){
          headerDiv.classList.remove("fixedToTop");
          headerDiv.style.top ="-7.2rem";
      }
      /* otherwise if we're scrolling up, fix the nav to the top */
      else{  
          headerDiv.classList.add("fixedToTop");
          headerDiv.style.top = "0";
      }
    
      prevScrollpos = currentScrollPos;
    }
    body{ margin: 0;}
    header {
        background: blue;
        height: 7.2rem;
        transition: all 0.2s ease-in-out;
        z-index: 100;
    }
    
    .content { 
        height:1000px; 
    }
    
    header.fixedToTop {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
    }
    
    /* add space for fixed header when it's fixed to top */
    header.fixedToTop + .content{
        margin-top:8rem;
    }
    <header></header>
    <div class="content" id="contentdiv">
    <h1>My Page</h1>
    <p>Content 1</p><p>Content 2</p><p>Content 3</p><p>Content 4</p><p>Content 5</p>
    <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
    <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
    </div>

    这是如何工作的

    我们需要从标题中移除固定定位并将其添加到我们将应用于滚动的类(例如fixedToTop)中:

    header {
        height: 7.2rem;
        transition: all 0.2s ease-in-out;
        z-index: 100;
    }
    header.fixedToTop {
        position: fixed;
        top: 0; left: 0; right: 0;
    }
    

    现在我们滚动功能的逻辑非常简单:

    1. 如果我们向下滚动,则让标题滚动到视图之外 - 删除 fixedToTop 类。
    2. 如果我们向上滚动,请添加我们的 fixedToTop 类,它会显示出来

    注意,我们需要显式设置top 的值以使过渡动画生效,因此我们也在代码中这样做。

    把这些放在一起,我们得到以下滚动函数:

    window.onscroll = function() {
      var currentScrollPos = window.pageYOffset;
    
      /* if scrolling down, let it scroll out of view as normal */
      if (prevScrollpos <= currentScrollPos ){
          headerDiv.classList.remove("fixedToTop");
          headerDiv.style.top ="-7.2rem";
      }
      /* otherwise if we're scrolling up, fix the nav to the top */
      else{  
          headerDiv.classList.add("fixedToTop");
          headerDiv.style.top = "0";
      }
    
      prevScrollpos = currentScrollPos;
    }
    

    2:标题是固定的,直到我们滚动经过它通常会消失的地方;向上滚动时固定在顶部

    在这种情况下,标题是固定的,直到我们滚动通过它会消失的“自然”位置。

    工作示例:

    var prevScrollpos = window.pageYOffset;
    
    /* Get the header element and it's position */
    var headerDiv = document.querySelector("header");
    var headerBottom = headerDiv.offsetTop + headerDiv.offsetHeight;
    
    window.onscroll = function() {
      var currentScrollPos = window.pageYOffset;
    
      /* if we're scrolling up, or we haven't passed the header,
         show the header at the top */
      if (prevScrollpos > currentScrollPos  || currentScrollPos < headerBottom){  
          headerDiv.style.top = "0";
      }
      else{
          /* otherwise we're scrolling down & have passed the header so hide it */
          headerDiv.style.top = "-7.2rem";
      } 
    
      prevScrollpos = currentScrollPos;
    }
    header {
        background: blue;
        height: 7.2rem;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        transition: top 0.2s ease-in-out;
        z-index: 100;
    }
    
    .content { 
        height:1000px; 
        margin-top:8rem; /* add space for fixed header */
    }
    <header></header>
    <div class="content" id="contentdiv">
    <h1>My Page</h1>
    <p>Content 1</p><p>Content 2</p><p>Content 3</p><p>Content 4</p><p>Content 5</p>
    <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
    <p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
    </div>

    这是如何工作的

    你的滚动函数中的逻辑是这样的:

    1. 如果我们向上滚动,则显示标题:
    2. 如果我们向下滚动...
    3. ...如果我们滚动通过了标题,请将其隐藏
    4. ...否则显示它

    把这些放在一起,我们得到以下滚动函数:

    
    var prevScrollpos = window.pageYOffset; // save the current position
    
    window.onscroll = function() {
       var currentScrollPos = window.pageYOffset;
    
      /* if we're scrolling up, or we haven't passed the header, show the header */
      if (prevScrollpos > currentScrollPos  || currentScrollPos < headerBottom){  
          headerDiv.style.top = "0";
      }
      else{
          /* otherwise we're scrolling down & have passed the header so hide it */
          headerDiv.style.top = "-7.2rem";
      } 
    
      prevScrollpos = currentScrollPos;
    }
    

    【讨论】:

    • 谢谢。一个问题:在 JavaScript 中是否可以使用“rem”度量?我认为它必须是像素?
    • 我们这里实际上并没有在 js 中使用 rem 值——我们设置的是 CSS 样式的值,它是要使用的 CSS,所以在这种情况下它很好 :)跨度>
    【解决方案2】:

    也许您可以将滚动位置与元素的高度进行比较:

    var prevScrollpos = window.pageYOffset;
    window.onscroll = function() {
       var currentScrollPos = window.pageYOffset;
       if (prevScrollpos > currentScrollPos) {
         document.querySelector("header").style.top = "0";
       } else if (currentScrollPos > document.querySelector("header").offsetHeight) {
         document.querySelector("header").style.top = "-7.2rem";
       }
       prevScrollpos = currentScrollPos;
    }
    
    header {
        background-color: rgb(255, 255, 255);
        height: 7.2rem;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        transition: top 0.2s ease-in-out;
        z-index: 100;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多