2012-09-14 47 views
5

我工作在页面上有一个固定的菜单,用户之后拿起滚动了从顶部一定距离,当他们向下滚动页面,从菜单中选择不同的链接中给出一个改变颜色的类。所有这些在Chrome和Safari中似乎都能很好地工作,但在Firefox中,页面在顶部冻结。我想知道它是否不断循环一些代码......实质上是冻结了窗口。window.scroll功能冻结火狐

这是我的代码。

$.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%,我似乎无法弄清楚为什么。

的问题是在代码与其他开始第三部分,如果(滚动< = 380)。我想通过消除的过程。任何人都可以看到它循环或做一些永远不会结束的事情......或者可以解释为什么firefox会在页面顶部冻结?

我是新来的这一切......我刚拿起的jQuery在过去的几天里,我已经基本google搜索了很多,适应代码,以便它适合我的需要。

任何帮助将不胜感激。

+0

你能给出一个链接到一个示例页面,显示问题,也许在jsfiddle.net或类似的东西? –

回答

3

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

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

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

+0

间隔是一个好主意。 setHash也选择了body而不是window,这也导致了一些问题。现在我有它的工作。现在是清理一些东西并开始缓存变量的时候了。谢谢你的帮助。 – Daniel

1

基本上你是在滚动事件执行太多。正如@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中必须有多慢。

0

除了其他问题,$('body').scrollTop()将始终在Firefox中返回0。当setHash()运行$('html,body').scrollTop(scrollmem);}时,它将跳转到屏幕的顶部,当用户第一次加载页面时,该屏幕看起来完全像被卡在屏幕的顶部。 $(window).scrollTop(),连同节流,将解决这个问题。