Miro
Miro

Reputation: 8650

scrollTop() flickers when used in loop to fix an element at top of page

Click on the second div and see how it stutters.

Demo: http://jsfiddle.net/mirohristov/76xtt3hm/

$("body").on('click', '.mysection', function(){
var el = $(this);

    if($(this).hasClass('active')){
        url = $('.active .nectar-button').attr('href');
        window.open(url, '_self')
    }else{


            $("html, body").animate({ scrollTop: el.offset().top+'px' }, 500,function(){
                el.addClass('active');

                var scroller = setInterval(function(){
                    $("html, body").scrollTop(el.offset().top);
                }, 50); //if i change this to 14 or 1 it works here but in my real case there is more content and images in the divs and it's like 150 here - it's sluggish or flickers
                $('.mysection').not(el).removeClass('active');
                setTimeout(function(){window.clearInterval(scroller)}, 1000);
            });

    }
});

In the real project, I'm using divs as pages to display content. The selected div should aligned with top of page while the div above is being 'closed'.

I used a loop to re-set the scrollTop to that of the element position but in my real example it, even though the setTitmeout delay is 14 or 1, it acts like in the demo (at 50 delay).

I belive it's because there's more content and full-width, HD background images that go fullscreen in my actual project. It's as if the setTimeout is updated slower than the CSS animation.

How can I make it smooth? Is it even possible?

Upvotes: 1

Views: 206

Answers (1)

Mottie
Mottie

Reputation: 86433

Try this (demo)

$('body').on('click', '.mysection', function () {
    var scroller,
        el = $(this),
        html = $('html')[0],
        body = $('body')[0];

    if ($(this).hasClass('active')) {
        url = $('.active .nectar-button').attr('href');
        window.open(url, '_self')
    } else {
        el.one('transitionend', function (e) {
            clearInterval(scroller);
        });
        $('html, body').animate({
            scrollTop: el.offset().top + 'px'
        }, 500, function () {
            el.addClass('active');
            scroller = setInterval(function () {
                var top = el.offset().top;
                html.scrollTop = top;
                body.scrollTop = top;
            }, 10);
            $('.mysection').not(el).removeClass('active');
        });
    }
});

Upvotes: 1

Related Questions