为什么我的动画会在Firefox中延迟?如何改进此滚动脚本?

时间:2014-06-16 16:13:52

标签: javascript jquery css firefox

我很难在Firefox中及时执行此代码。它似乎在Chrome中运行得很好。

JSFiddle:http://jsfiddle.net/EXDhb/

我正在使用的实时示例页面:http://mindevo.com/tests/tacos.html

我不确定我是否会遗漏一些东西。我通过阅读其他人组合在一起的一系列页面滚动脚本来一起攻击它。不确定这对我来说是否是最好的方式来做我想要完成的事情(这会使下一个区域变暗,直到它有点显露出来。(我中途使用过)。

这是我的javascript:

$(document).ready(function(){
 $(window).scroll(function(){
  $('.dark').each(function(i){

   var half_object = $(this).position().top + ($(this).outerHeight()/2);
   var bottom_window = $(window).scrollTop() + $(window).height();
   var bottom_object = $(this).position().top + $(this).outerHeight();

   if(bottom_window > half_object){
    $(this).animate({'opacity':'1'},200);
   }
   else if(bottom_object > $(window).scrollTop()) {
    $(this).animate({'opacity':'.5'},200);
   }
  });
 });
});

有更好的方法吗?我尝试添加/删除css类但它引用了一些我不满意的疯狂Chrome错误。

为什么它在Firefox中运行得这么慢?

3 个答案:

答案 0 :(得分:2)

首先没有6个独立的jQuery $(this)操作和多个$(window)!尽可能使用临时变量以避免重新查询。

JSFIddle:http://jsfiddle.net/TrueBlueAussie/EXDhb/9/

$(document).ready(function () {
    // window never changes
    var $window = $(window);
    $window.scroll(function () {
        // Window height may have changed between scrolls
        var windowHeight = $window.height();
        var scrollTop = $window.scrollTop();
        $('.dark').each(function (i) {
            var $this = $(this);
            var top = $this.position().top;
            var outerH = $this.outerHeight();
            var half_object = top + (outerH / 2);
            var bottom_window = scrollTop + windowHeight;
            var bottom_object = top + outerH;

            console.log(half_object);

            if (bottom_window > half_object) {
                $this.stop().animate({
                    'opacity': '1'
                }, 200);
            } else if (bottom_object > scrollTop) {
                $this.stop().animate({
                    'opacity': '.5'
                }, 200);
            }
        });
    });
});

依此类推,直到你不做任何两次你不需要的开销。

更新:停止以前的动画

暂停不是由上面代码的速度引起的,而是由于没有停止多个动画。问题是scroll经常发生火灾,因此如果没有.stop()动画排队并一个接一个地开火。这使它看起来实际上要慢得多。

进一步的优化可能只涉及处理实际屏幕上的元素,但鉴于现在的速度明显,这是毫无意义的。

答案 1 :(得分:1)

您可以缓存变量,这应该有所帮助:

$(document).ready(function(){
    var $window = $(window);

    $window.scroll( function(){
        $('.dark').each(function(i){
            var $this = $(this);
            var outerHeight = $this.outerHeight();
            var positionTop = $this.position().top;
            var half_object = positionTop + (outerHeight/2);
            var bottom_window = window.scrollTop() + window.height();
            var bottom_object = positionTop + outerHeight;

            if(bottom_window > half_object){
                $this.animate({'opacity':'1'}, 200);
            } else if(bottom_object > window.scrollTop()) {
                $this.animate({'opacity':'.5'}, 200);
            }
        });
    });
});

答案 2 :(得分:1)

我意识到已经有一个已接受的答案,但很多时候只有在用户停止滚动后才做某事很有用,而不是每次“滚动”事件触发时都这样做。这个事件每秒可以发射超过50次,你可以用~20ms做你需要做的事情。 This other StackOverflow question向您展示了滚动停止后如何做某事。正如@TrueBlueAussie在他的回答中提到的,你仍然想要停止当前正在运行的任何动画。