relic
relic

Reputation: 1704

Window scroll event causing IE to lag badly, when using mouse wheel

I have a navigation container near the top of the page that should add or remove the classname "stuck" (switching between position:static and position:fixed) when the page scrolls beyond a certain value. Seems to work fine in FF and Chrome, but of course IE (7,8 and 9) is having trouble.

The page lags heavily (essentially unusable) when scrolling using the mousewheel, although if I grab and drag the horiz scrollbar then the page slides smoothly with no lag.

My searching around revealed that it's probably because IE executes way more scroll events than the other browsers, but I can't figure out exactly how to throttle the number of events being fired. You can see in the code block below that I'm also using a 'scroll stop' solution but I really need to also be able to execute a callback WHILE the user is still scrolling when they go beyond a certain point on the page.

I thought the way I was implementing it was pretty and stripped down and basic, but is there a better way to handle this, at least just for IE?

var scrollValue = 0;
var scrollTimer = false;

$(window).bind('scroll', function(){
    scrollValue = $(window).scrollTop();

    // SET TIMER DELAY FOR SCROLL-STOP
    if (scrollTimer) {
        clearTimeout(scrollTimer);
    }
    scrollTimer = setTimeout(scrollStopped, 25);

    // STICK/UNSTICK HEADER
    if (scrollValue > 320){
        if (!$(stickyWrap).hasClass('stuck')){
            $(stickyWrap).addClass('stuck')
        }
    } else {
        if ($(stickyWrap).hasClass('stuck')){
            $(stickyWrap).removeClass('stuck');
        }
    }
});

Upvotes: 4

Views: 4003

Answers (1)

FiLeVeR10
FiLeVeR10

Reputation: 2165

Down with timeout, up with switch

If you made the jQuery a little more simple, and added a switch to only execute anything once before and after the threshold, it should speed things up nicely.

var header = $('.stickyWrap'),
    trig = 320,
    go = true;

$(window).bind('scroll', function(){
    var scrollValue = $(this).scrollTop();

    if ((go && scrollValue > trig) || (!go && scrollValue <= trig)) {//before or after
        header.toggleClass('stuck');//toggle class
        go ? go = false : go = true;//toggle boolean
    }
});

Now it will only try to execute anything only once before and once after it crosses the threshold of 320.

Made A Fiddle >

Upvotes: 1

Related Questions