比$(window).scroll更快的替代方案是什么?

4
我注意到使用$(window).scroll的jQuery滚动绑定会导致页面明显变慢。例如,我在我的页面上使用以下脚本,当我滚动过它们时,页面上的元素会改变样式:
$(window).scroll(function() {
     var bottom_of_window = $(window).scrollTop() + $(window).height();
     $('.ElementsToBeChanged').each(function() { 
            var bottom_of_object = $(this).offset().top + $(this).outerHeight();
            if (bottom_of_window > bottom_of_object) {
                //Add my styles
            }
        });

});

可以理解为网站一直在滚动时会导致网站变卡,但我还没有找到任何替代方案来触发当对象被滚过时的事件。这种在滚动时触发事件的网站似乎很常见;它们使用什么方法来避免这种卡顿?


一个常见的解决方案是,不要在每个“滚动”事件上都执行你的代码,而是每隔一段时间才执行。 - Derek 朕會功夫
不是完整的答案,但以下几点可以帮助加快速度:
  1. 使用underscore的防抖函数。只有在自上次调用以来经过一定时间后才会触发事件:http://underscorejs.org/#debounce
  2. 保留对象引用。目前,每次滚动时都会查询两次窗口,然后查询所有类名为“ElementsToBeChanged”的元素,然后在其中为每个“ElementsToBeChanged”查询两次$(this)。您可以通过至少将“ElementsToBeChanged”的查询从滚动函数中提取出来来改进此操作。
- jas7457
2
https://johnresig.com/blog/learning-from-twitter/ - Phix
1个回答

0

拖慢性能的不是滚动功能本身,而是在每次滚动事件中对每个项目进行大量计算。

但是尽管如此,在屏幕上显示20个元素时,我并没有看到性能下降。

尝试将window对象缓存为变量[例如:win = $(window)],并使用each函数中的el代替this

与直接使用jQuery更改CSS相比,尝试添加/删除类。

不要像其他人提到的那样使用denounce,因为它只会在停止滚动时触发。你要找的是throttling

以下是我想出来的方法,在我的电脑上对于20个元素效果良好:

var win = $(window);

win.scroll(function() {
     var bottom_of_window = win.scrollTop() + win.height();
     $('.ElementsToBeChanged').each(function(index,el) { 
            var bottom_of_object = $(el).offset().top + $(el).outerHeight();
            if (bottom_of_window > bottom_of_object) {
                $(el).addClass('red');
            }else{
              $(el).removeClass('red');
            }
        });

});
.ElementsToBeChanged{
  margin:100px;
  height:200px;
  border:1px solid black;
  transition:2s;
}

.ElementsToBeChanged.red{
  background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>
<div class="ElementsToBeChanged">.ElementsToBeChanged</div>

最后,只需使用像Skrollr.jsScrollMagic这样的插件即可。

1
你的解决方案帮了我很大的忙 - 谢谢! 我一直在尝试使用 velocity.js 动画来加速我的页面 - 只添加类会更快吗? - user8887068
很高兴能帮忙。是的,使用纯CSS添加类和动画比任何插件都要快。干杯。 - Miro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接