CampbeII
CampbeII

Reputation: 81

window scroll method flickers in IE

This may come as a huge surprise to some people but I am having an issue with the IE browser when I am using the $(window).scroll method.

My goal: I would like to have the menu located on the left retain it's position until the scroll reaches > y value. It will then fix itself to the top of the page until the scroll returns to a < y value.

My error: Everything seems just fine in Chrome and Firefox but when I go to Internet Explorer it would seem the browser is moving #scroller every time the scroll value changes, this is causing a moving/flickering event.

If someone could point me to a resource or give me a workaround for this I would be very grateful!

Here is a fiddle: http://jsfiddle.net/CampbeII/nLK7j/

Here is a link to the site in dev: http://squ4reone.com/domains/ottawakaraoke/Squ4reone/responsive/index.php

My script:

$(window).scroll(function () {
    var navigation = $(window).scrollTop();
    if (navigation > 400) {
        $('#scroller').css('top',navigation - 220);
    } else {
        $('#scroller').css('top',183);
        $('#scroller').css('position','relative');
    }
});

Upvotes: 4

Views: 5333

Answers (3)

Useless Code
Useless Code

Reputation: 12402

You might want to take a look at the jQuery Waypoints plugin, it lets you do sticky elements like this and a lot more.

If you want to stick with your current method, like the other answers have indicated you should toggle fixed positioning instead of updating the .top attribute in every scroll event. However, I would also introduce a flag to track whether or not it is currently stuck, this way you are only updating the position and top attributes when it actually make the transition instead of every scroll event. Interacting with the DOM is computationally expensive, this will take a lot of load off of the layout engine and should make things even smoother.

http://jsfiddle.net/WYNcj/6/

$(function () {
  var stuck = false,
      stickAt = $('#scroller').offset().top;

  $(window).scroll(function () {

    var scrollTop = $(window).scrollTop();

    if (!stuck && scrollTop > stickAt) {
      $('#scroller').css('top', 0);
      $('#scroller').css('position','fixed');
      stuck = true;
    } else if (stuck && scrollTop < stickAt) {
      $('#scroller').css('top', stickAt);
      $('#scroller').css('position','absolute');
      stuck = false;
    }
  });
});

Update

Switching the #scroller from relative to fixed removes it from the normal flow of the page, this can have unintended consequences for the layout as it re-flows without the missing block. If you change #scroller to use an absolute position it will be removed from the normal flow and will no longer cause these side-effects. I've updated the above example and the linked jsfiddle to reflect the changes to the JS/CSS.

I also changed the way that stickAt is calculated as well, it uses .offset() to find the exact position of the top of #scoller instead of relying on the CSS top value.

Upvotes: 2

atondelier
atondelier

Reputation: 2434

Instead of setting the top distance at each scroll event, please consider only switching between a fixed position and an absolute or relative position.All browsers will appreciate and Especially IE.

So you still listen to scroll but you now keep a state flag out of the scroll handler and simply evaluate if it has to switch between display types.

That is so much more optimized and IE likes it.

Upvotes: 1

Jeremy
Jeremy

Reputation: 437

I can get flickers in Chrome as well if I scroll very quickly. Instead of updating the top position on scroll, instead used the fixed position for your element once the page has scrolled below the threshold. Take a look at the updated fiddle: http://jsfiddle.net/nLK7j/2/

Upvotes: 0

Related Questions