修复了一个非常滞后的JavaScript滚动事件

时间:2017-02-09 23:28:46

标签: javascript html css

这个想法是,一旦页面滚动到某个点,背景图像将变为固定并部分移出屏幕(想想手机上的推特)。

当前的JavaScript是:

<script>
window.addEventListener('scroll', function () 
{
    document.body.classList
  [
    window.scrollY <= 750 ? 'add': 'remove'
  ]

  ('notscrolled');
});

window.addEventListener('scroll', function () 
{
  document.body.classList
    [
          window.scrollY >= 750 ? 'add': 'remove'
      ]
  ('scrolled');
});
</script>

每次滚动页面时,此实现显然都会触发,从而使页面非常滞后且无法忍受。

我有什么方法可以改善这一点,以消除滞后并加快页面速度?

3 个答案:

答案 0 :(得分:1)

以下可能有效。你没有提供太多的细节,所以根据你提供的我设置超过250.有一个计时器,每次你滚动它将清除和重置。然后,当您不再滚动时,它将执行定时功能(仅在您停止滚动并且没有消耗时间之后)您可以更改时间和条件。

    var js = {
		cl: "classList",
		sy: "scrollY",
		pyo: "pageYOffset",
	};

    var nav = document.getElementById("header");
    var timer;
	
	
	function ss2(e){
        window.clearTimeout(timer);
        timer = window.setTimeout(function(){
      
		var mm, cl;
		
		cl = nav[js.cl];
		if((mm = window[js.sy] || window[js.pyo]) > 250){
			if(!cl.contains("mutate")){
				cl.add("mutate");
			}
		}
		else{
			cl.remove("mutate");
		}
          
        }, 250);
	};


    document.addEventListener("scroll", ss2);
body{
    height: 5000px;
}
#header{
    width: 100%;
    height: 50px;
    background: #f7f8f9;
}
.mutate{
    position: fixed !important;
    background: salmon !important;
}
<div id="header">
  
</div>

答案 1 :(得分:1)

您发布的代码中唯一明显的错误是在 String encodedUrl = URLEncoder.encode(<url>); 上添加了两个事件,而不是一个。 scroll 相当昂贵,所以在理论和实践中,这应该更快:

scroll

除非window.addEventListener("scroll",function(){ window.scrollY<750 ? (document.body.classList.remove("scrolled"), document.body.classList.add("notscrolled")): (document.body.classList.add("scrolled"), document.body.classList.remove("notscrolled")) }); 滚动点从一侧传递到另一侧,否则脚本不会触发重绘/重排,但同样适用于您的脚本。

如果它仍然滞后,请考虑创建一个最简单,完整且可验证的问题示例。到目前为止,我还没有能够在任何设备上的任何浏览器中体验它。

还有比你所展示的更多的东西。

答案 2 :(得分:1)

绝对!您所描述的是用于限制事件流的经典用例。这通常也被称为背压&#39;在处理限制,去抖动和类似技术等机制时,可以平滑滚动事件的性能。

最简单直接的方法是使用已编码的实现,例如lodash&#39; _throttle方法:

https://www.npmjs.com/package/lodash.throttle

如果您想了解更多关于限制和去抖动的信息,可以在这里:

https://css-tricks.com/debouncing-throttling-explained-examples/

&#13;
&#13;
$(document).ready(function(){

  var $rawDiv = $('#raw-events'),
      $debounceDiv = $('#debounced-events'),
      $scrollArea = $('.scroll-area'),
      initialized = false,
      frequency = 100,
      barLength = 0,
      globalColor = 2,
      colorNeedChange = false,
      interval_id,
      rawColor = 0,
      debounceColor = 0,
      maxBarLength = 87;
  
  var throttledEvent = _.throttle(function(div){
   debounceColor = globalColor;
  }, frequency*5, {'trailing': true});
  

  var changeDebouncedColor = _.debounce(function(div){
    // Change colors, to visualize easier the "group of events" that is reperesenting this debounced event
    
    globalColor++;
    if (globalColor > 9){
      globalColor = 2;
    } 
  }, frequency*4, {leading:false, trailing:true});
  

  function draw_tick_marks(){

      // every x seconds, draw a tick mark in the bar
      interval_id = setInterval(function(){
      barLength++;   
      $rawDiv.append('<span class="color' + rawColor + '" >');
      $debounceDiv.append('<span class="color' + debounceColor + '" >');
      rawColor = 0; 
      debounceColor = 0;
        
      if (barLength > maxBarLength){
        clearInterval(interval_id);
      }
      
    }, frequency);
  };
  
  
  // Track Mouse movement or clicks for mobile
  $scrollArea.on('scroll', function (){  
    if (!initialized) {
      initialized = true;
      draw_tick_marks();
      $(this).addClass('active');
    } 
    rawColor = globalColor;
    throttledEvent();
    changeDebouncedColor();
  });

  $('.reset').on('click', function(){
    initialized = false;
    $scrollArea.removeClass('active');
    $rawDiv.empty();
    $debounceDiv.empty();
    barLength = 0;
    clearInterval(interval_id);
  });

});
&#13;
body {
   background: #ddd;
   color: #000;
   font: 15px/1.51 system, -apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif;
   margin:0 auto;
   max-width:600px;
   padding:20px;
}

.events{
  padding:0px 20px 10px 20px;
  height: 23px;
}
.events span {
  height:17px;
  width:6px;
  display:inline-block;
  border-right:1px solid #111;

}
.events span:last-of-type {
  border:2px solid black;
  border-bottom: 4px solid #AAA;
  border-top: 0px;
  margin-bottom:-17px;
  margin-left:-2px;
}
h2 {
  margin:10px 0 5px 0;
  clear:both;
  font-weight: normal;
  font-size:14px;
  padding:6px 20px;
}

.scroll-area {
  width: 100%;
  overflow-y: scroll;
}

.scroll-slug {
  width: 18000px;
  height: 50px;
  background:
linear-gradient(45deg, #92baac 45px, transparent 45px)64px 64px,
linear-gradient(45deg, #92baac 45px, transparent 45px,transparent 91px, #e1ebbd 91px, #e1ebbd 135px, transparent 135px),
linear-gradient(-45deg, #92baac 23px, transparent 23px, transparent 68px,#92baac 68px,#92baac 113px,transparent 113px,transparent 158px,#92baac 158px);
background-color:#e1ebbd;
background-size: 128px 128px;
}

.trigger-area.active {
  background:#2F5065;
}
.clickme:hover,
.clickme:active{
  background-color: #333;
}
.clickme:active{
  padding: 4px 5px;
}
.reset {
  display:inline-block;
  padding: 10px;
  text-align: center;
  font-size:24px;
  cursor:pointer;
  border: 1px solid white;
}
.visualizations {
  margin-top:10px;
  background:rgba(0,0,0,0.3);
}
.details {
  font-size:13px;
  color:#999;
}

/* stating the obvious: color0 represents our empty color */
.color0 { transparent}

.color1 { background-color: #FFE589}
.color2 { background-color: #B9C6FF}
.color3 { background-color: #99FF7E}
.color4 { background-color: #FFB38A}
.color5 { background-color: #A5FCFF}
.color6 { background-color: #FF8E9B}
.color7 { background-color: #E3FF7E}
.color8 { background-color: #FFA3D8}
.color9 { background-color: #5ca6ff}
.color10 { background-color: #9BFFBB}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a class="reset">Reset Timer</a>
<div class="visualizations">
<h2>Raw events over time</h2>
<div id="raw-events" class="events"></div>
<h2>Throttled events
  <span class="details"> 300ms, trailing</span></h2>
<div id="debounced-events" class="events"></div>
<div class="scroll-area">
  <div class="scroll-slug"></div>
</div>  

</div>
&#13;
&#13;
&#13;

查看代码段。我已经修改了其中一个示例,以便在滚动时显示限制。来回滚动图案区域。看看顶部如何不断射击。看看底部的一个如何经常这样。改变频率。

要指出的第二件事是你要附加多个事件来滚动。请记住,我们受限制的原因是因为那件事就像疯了一样!

  • 仅附加一个事件处理程序
  • 限制处理功能的触发。

这是你修复滚动性能的方法。