window.scroll函数冻结firefox



我正在处理一个带有固定菜单的页面,该菜单在用户从顶部滚动一定距离后会出现,当他们向下滚动页面时,菜单中的不同链接会被赋予一个更改颜色的类。所有这些在Chrome和Safari中似乎都能很好地工作,但在Firefox中,页面会在顶部冻结。我想知道它是否在不停地循环通过一些代码。。。基本上冻结了窗户。

这是我的密码。

$.localScroll({
    onBefore: function() {
        $('body').data('scroll-executing', true);
    },
    onAfter: function() {
        $('body').data('scroll-executing', false);
        $(window).trigger("scroll");
    }
});
$(window).scroll(function () {
    if ($(this).scrollTop() > 259) {
        $('.nav').addClass("f-nav");
    } else {
        $('.nav').removeClass("f-nav");
    }
});
$(window).scroll(function() { 
    if ($('body').data('scroll-executing')) {
        return;
    }
    // find the a with class 'active' and remove it
    $("a").removeClass('active');
    // get the amount the window has scrolled
    var scroll = $(window).scrollTop();
    // add the 'active' class to the correct #nav based on the scroll amount
    if (scroll > 2150) {
        $("#nav_3").removeClass('active');
        $("#nav_5").attr('class', 'active');
        setHash("contact");
    } else if (scroll > 1300) {
        $("#nav_2").removeClass('active');
        $("#nav_3").attr('class', 'active');
        setHash("portfolio");
    } else if (scroll > 400) {
        $("#nav_2").attr('class', 'active');
        setHash("about");
    } else if (scroll <= 380) { //when I remove this section, the problem goes away.
        $("#nav_1").attr('class', 'active');
        setHash("home");
    }
});

我忘了添加setHash定义。给你。

setHash = function(hash) {
    var scrollmem = $('body').scrollTop();
    window.location.hash = hash;
    $('html,body').scrollTop(scrollmem);
}

我还注意到CPU达到了100%,我似乎不明白为什么。

问题出现在代码的第三部分,以else-if(滚动<=380)开头。我通过消除的过程弄明白了这一点。有人能看到它循环或做一些永远不会结束的事情吗。。。或者解释为什么firefox会在页面顶部冻结?

我对这一切都很陌生。。。在过去的几天里,我刚学会了jquery,基本上我已经在谷歌上搜索了很多,并对代码进行了调整,使其符合我的需求。

如有任何帮助,我们将不胜感激。

在滚动事件上执行太多代码是过度的,在每次滚动时,浏览器会触发滚动事件一百次,您可以考虑使用具有throttledebounce等方法的库。

http://documentcloud.github.com/underscore/#throttle

将处理程序附加到窗口滚动事件是一个非常非常糟糕的主意根据浏览器的不同,滚动事件可能会触发很多,在滚动回调中放入代码会减慢滚动页面的速度(这不是一个好主意)。因此,滚动处理程序的任何性能下降都只会使滚动的整体性能更加复杂。相反,最好使用某种形式的计时器每隔X毫秒检查一次,或者附加一个滚动事件,只在延迟后(甚至在给定的执行次数后,然后延迟)运行代码。http://ejohn.org/blog/learning-from-twitter/

基本上,您在滚动事件中执行了太多。正如@undefined所说,浏览器对此的调用比你想象的要多得多。一些提示:

当在一个将被多次调用的函数内部时,请已经创建jQuery对象。这样,每次调用函数时,都不会重新创建相同的jQuery对象。

var nav2 = $("#nav_2");
$(window).scroll(function() {
   ...
   nav2.removeClass('active');
   ...
});

类似地,当一次又一次地调用时,添加和删除类可能会消耗大量的处理周期——尤其是当您访问一整类元素时,比如在$('.nav').addClass("f-nav");中。

相反,只有当类不存在时,才尝试添加/删除这些类。类似于:

var alreadyAdded = false;
var alreadyRemoved = false;
$(window).scroll(function () {
    if ($(this).scrollTop() > 259) {
      if(!alreadyAdded){
        $('.nav').addClass("f-nav");
        alreadyAdded = true;
        alreadyRemoved = false;
      }
    } else if(!alreadyRemoved) {
        $('.nav').removeClass("f-nav");
        alreadyAdded = false;
        alreadyRemoved = true;
    }
});

尽管如此,它可能仍然会缓慢滚动,所有这些代码都附加到滚动事件中。也许还有其他方法可以得到同样的效果。如果firefox正在冻结,我只能想象在IE中它的速度有多慢。

除了其他问题外,$('body').scrollTop()在Firefox中总是返回0。当setHash()运行$('html,body').scrollTop(scrollmem);}时,它会跳到屏幕顶部,这看起来就像用户第一次加载页面时被卡在屏幕顶部一样。$(window).scrollTop()与节流相结合将解决这个问题。

最新更新