I'm working on a page with a fixed menu that picks up after the user has scrolled a certain distance from the top, and as they scroll down the page, different links from the menu are given a class that changes the color. All of this seems to work well in Chrome and Safari, but in Firefox, the page freezes at the top. I'm wondering if it is looping through some code incessantly...essentially freezing the window.
Here is my code.
$.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");
}
});
I forgot to add the setHash definition. Here it is.
setHash = function(hash) {
var scrollmem = $('body').scrollTop();
window.location.hash = hash;
$('html,body').scrollTop(scrollmem);
}
I also noticed that the CPU goes up to 100%, and I can't seem to figure out why.
The problem is in the third section of code beginning with else if (scroll <= 380). I figured that out by process of elimination. Can anybody see it looping or doing something that will never end...or would explain why firefox freezes at the top of the page?
I'm new to all of this...I just picked up jquery in the past few days, and I have basically been googling a lot and adapting code so that it fits what I need.
Any help will be greatly appreciate.
In addition to the other issues,
$('body').scrollTop()
will always return 0 in Firefox. WhensetHash()
runs$('html,body').scrollTop(scrollmem);}
, it will jump to the top of the screen, which looks exactly like being stuck at the top of the screen when the user first loads the page.$(window).scrollTop()
, in conjunction with throttling, will solve this problem.Basically you are executing too much in the scroll event. As @undefined said, the browser calls this a lot more than you might think. Some tips:
When inside a function that will be called many times, have your jQuery objects already created. That way, each time the function is called, it's not recreating the same jQuery object.
Similarly, when called over and over again, adding and removing classes can consume a lot of your processing cycles - Especially when you are accessing a whole class of elements, like in
$('.nav').addClass("f-nav");
.Instead, try to add/remove the classes only if they don't exist. Something like:
All that said, it will still probably scroll slowly with all this code attached to the scroll event. Maybe there is another way you can get the same effect. If firefox is freezing, I can only imagine how slow this must be in IE.
Executing too much code on scroll event is overkill, on each scroll, browsers trigger the scroll event hundred times, you can consider using a library that have methods like
throttle
ordebounce
.http://documentcloud.github.com/underscore/#throttle