【问题标题】:Performance issue with hiding header on scrolling in javascript在javascript中滚动时隐藏标题的性能问题
【发布时间】:2019-06-25 17:44:39
【问题描述】:

我正在尝试构建一个导航栏:

  • 从高处开始
  • 向下滚动时隐藏
  • 向上滚动时显示缩小版本
  • 完全滚动到顶部时会增长到全高

到目前为止,我找到了一种可行的方法。但必须有更有效的方法。我有一个隐藏和显示导航栏的功能——当我到达顶部时,一个间隔会再次增长。我尝试将它们结合起来,但总是失败...谢谢!

HTML

<!DOCTYPE html>
  <html>
    <head>
      <title>Test</title>
    </head>
    <body>
      <header id="navbar" class="navbar">
        <a href="#home">Home</a>
        <a href="#news">News</a>
        <a href="#contact">Contact</a>
      </header>
    </body>
  </html>

JavaScript

var prevScrollpos = window.pageYOffset;
var shrinkHeader = 200;
function tellMeAStory() {
}

window.onscroll = function() {
  var currentScrollPos = window.pageYOffset;
  if (prevScrollpos > currentScrollPos) {
    document.getElementById("navbar").style.top = "0";
  } else {
    document.getElementById("navbar").style.top = "-200px";
    $('.navbar').addClass('shrink');
  }

  prevScrollpos = currentScrollPos;
}

setInterval(function(){
  var scroll = getCurrentScroll();
   if (scroll < 10){
    $('.navbar').removeClass('shrink');
  } else {}
},250)

function getCurrentScroll() {
    return window.pageYOffset || document.documentElement.scrollTop;
    };

CSS

body {
  margin: 0;
  background-color: #f1f1f1;
  font-family: Arial, Helvetica, sans-serif;
  height: 2000px;
}

header {
  background-color: #333;
  position: fixed;
  top: 0;
  width: 100%;
  display: block;
  transition: all 0.3s;
  height: 200px;
}

.grow{
  height: 200px;
}

.shrink{
  height: 50px;
}

#navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 15px;
  text-decoration: none;
  font-size: 17px;
}

#navbar a:hover {
  background-color: #ddd;
  color: black;
}

JSFiddle

https://jsfiddle.net/Jimmey/wry54an7/4/

【问题讨论】:

    标签: javascript jquery html css performance


    【解决方案1】:

    以下是我会做的一些改进:

    • 删除 jQuery,因为您只使用它添加或删除一个类。
    • 缓存您的选择器,尤其是当它们处于循环中时。
    • Throttle your scroll event,因为它可以高速发射。
    • 删除这里不需要的setInterval 函数。

    var prevScrollpos = getCurrentScroll();
    var shrinkHeader = 200;
    var ticking = false;
    
    // Cache it so you don't have to get it on every scroll event
    var navbar = document.getElementById('navbar');
    
    window.addEventListener('scroll', function() {
      var currentScrollPos = getCurrentScroll();
    
      if (!ticking) {
        window.requestAnimationFrame(function() {
          if (prevScrollpos > currentScrollPos) {
            navbar.style.top = '0';
          } else {
            navbar.style.top = '-200px';
            navbar.classList.add('shrink');
          }
    
          if (currentScrollPos < 10) {
            navbar.classList.remove('shrink');
          }
    
          prevScrollpos = currentScrollPos;
          ticking = false;
        });
    
        ticking = true;
      }
    });
    
    function getCurrentScroll() {
      return window.pageYOffset || document.documentElement.scrollTop;
    };
    body {
      margin: 0;
      background-color: #f1f1f1;
      font-family: Arial, Helvetica, sans-serif;
      height: 2000px;
    }
    
    header {
      background-color: #333;
      position: fixed;
      top: 0;
      width: 100%;
      display: block;
      transition: all 0.3s;
      height: 200px;
    }
    
    .grow {
      height: 200px;
    }
    
    .shrink {
      height: 50px;
    }
    
    #navbar a {
      float: left;
      display: block;
      color: #f2f2f2;
      text-align: center;
      padding: 15px;
      text-decoration: none;
      font-size: 17px;
    }
    
    #navbar a:hover {
      background-color: #ddd;
      color: black;
    }
    <header id="navbar" class="navbar">
      <a href="#start">Start</a>
      <a href="#one">One</a>
      <a href="#two">Two</a>
    </header>

    【讨论】:

      【解决方案2】:

      将它们结合起来并不难。我建议这样做:

      var prevScrollpos = window.pageYOffset;
      var shrinkHeader = 200;
      
      window.onscroll = function() {
      var currentScrollPos = window.pageYOffset;
        if (currentScrollPos < 10){
          $('.navbar').removeClass('shrink');
        }
        else if (prevScrollpos > currentScrollPos) {
          document.getElementById("navbar").style.top = "0";
        } else {
          document.getElementById("navbar").style.top = "-200px";
          $('.navbar').addClass('shrink');
        }
      
        prevScrollpos = currentScrollPos;
      }
      
      function getCurrentScroll() {
          return window.pageYOffset || document.documentElement.scrollTop;
      };
      

      您还可以跟踪最后一次操作,如果相同,则不要对厄运进行任何操作(这样会更快)。

      使用类而不是内联样式也是一个好习惯。您可能需要考虑使用类来显示/隐藏栏。你可以只有 3 个类并且不需要内联样式:

      Fiddle example for classes

      【讨论】:

        猜你喜欢
        • 2020-02-17
        • 2018-05-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多