【问题标题】:Does JavaScript keep firing the if statement on scroll when it already fired once?当 JavaScript 已经触发一次时,它是否会继续触发滚动时的 if 语句?
【发布时间】:2018-06-25 09:05:00
【问题描述】:

我在滚动标题上做了 2 个固定:

var header = document.getElementsByClassName("header");

function headerChange(){
  if(header[1].getBoundingClientRect().top <= 70){
    header[0].classList.add("fixed-removal");
  } else {
  header[0].classList.remove("fixed-removal");
  
  }
  
  if(header[0].getBoundingClientRect().top <= -70){
    header[1].classList.add("fixed-add");
  } else {
  header[1].classList.remove("fixed-add");
  }
}

document.addEventListener("scroll", headerChange);
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

.header {
 width: 100%;
 height: 70px;
 font-family: Arial, sans-serif;
 font-size: 2em;
}

.content {
width: 100%;
height: 100%;
background-color: yellow;}

.header:nth-of-type(1){
  position: fixed;
  background-color: dodgerblue;
}

.header:nth-of-type(2){
  background-color: red;
}

.fixed-removal {
  position: absolute !important;
  bottom: 0;
}

.fixed-add {
  position: fixed;
  top: 0;
}

.content:nth-of-type(2){
margin-bottom: 200px;
}
<header class="header">HEADER 1</header>
<div class="content"></div>
<header class="header">HEADER 2</header>
<div class="content"></div>

一切正常……这就是问题所在。现在我只有 2 个滚动固定标题,但是当我有更多标题时,JavaScript 是否会继续在滚动时触发 if/else 语句?我担心CPU性能,这就是原因。 我不希望它无缘无故地运行,只是为了限制性能。尤其是 else 声明。

请不要 jQuery 答案

【问题讨论】:

    标签: javascript html css scroll


    【解决方案1】:

    当您滚动时,scroll 事件侦听器会一直触发,因此您的函数也会被调用。

    通过使用 节流 事件处理程序,您可以承担大量工作负载,并选择调用函数的速率。

    这是一个使用setTimeout,借用于:

    请注意,在上面的链接中,您会找到更多关于如何限制处理程序的版本

    堆栈sn-p

    var header = document.getElementsByClassName("header");
    
    function headerChange(){
      if(header[1].getBoundingClientRect().top <= 70){
        header[0].classList.add("fixed-removal");
      } else {
      header[0].classList.remove("fixed-removal");
      
      }
      
      if(header[0].getBoundingClientRect().top <= -70){
        header[1].classList.add("fixed-add");
      } else {
      header[1].classList.remove("fixed-add");
      }
    }
    
    (function(timeout) {
    
      window.addEventListener("scroll", scrollThrottler, false);
    
      function scrollThrottler() {
        // ignore scroll events as long as an actualScrollHandler execution is in the queue
        if ( !timeout ) {
          timeout = setTimeout(function() {
            timeout = null;
            actualScrollHandler();
         
           // The actualScrollHandler will execute at a rate of 15fps
           }, 66);
        }
      }
    
      function actualScrollHandler() {
        // handle the resize event
        headerChange();
      }
    
    }());
    html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    }
    
    .header {
     width: 100%;
     height: 70px;
     font-family: Arial, sans-serif;
     font-size: 2em;
    }
    
    .content {
    width: 100%;
    height: 100%;
    background-color: yellow;}
    
    .header:nth-of-type(1){
      position: fixed;
      background-color: dodgerblue;
    }
    
    .header:nth-of-type(2){
      background-color: red;
    }
    
    .fixed-removal {
      position: absolute !important;
      bottom: 0;
    }
    
    .fixed-add {
      position: fixed;
      top: 0;
    }
    
    .content:nth-of-type(2){
    margin-bottom: 200px;
    }
    <header class="header">HEADER 1</header>
    <div class="content"></div>
    <header class="header">HEADER 2</header>
    <div class="content"></div>

    【讨论】:

      【解决方案2】:

      每个滚动像素都会触发 javascript 滚动事件*。这是一个非常沉重的事件。

      您可能想要这个,但我推荐debounce or dethrottle 处理程序,它基本上将调用量减少到每秒可配置的次数,因此您可以在性能和结果之间进行优化。

      减速:

      去抖:

      如果你只想发生一次,you can remove the eventhandler:

      document.removeEventListener("scroll", headerChange);
      

      *一些浏览器每几个像素就可以做到这一点,但仍然很多。

      【讨论】:

      • 所以你的意思是我应该分离并重新附加事件侦听器,并且只有一个函数是附加其他函数的事件处理程序?
      • 你不是说document.removeEventListener吗?
      • 哈哈是的。 @MWR:不。这是代码的强度,而不是函数的数量。我建议您阅读 dethrottle/debounce,因为这将解释您在寻找什么:)
      猜你喜欢
      • 2012-07-06
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多