Hiding nav on scroll down not working with barba.js page transitions

时间:2017-08-05 11:06:57

标签: javascript jquery scroll

Scroll Setup

I'm using the popular scroll detection method to hide a nav element on scroll down and show it on scroll up.

$(window).scroll(function(){

    currentScrollTop = $(window).scrollTop();

    if (currentScrollTop > lastScrollTop) {
        // On scroll down
        $('nav').removeClass('active');
        console.log('Down');
    } else {
        // On scroll up
        $('nav').addClass('active');
        console.log('Up');
    }

    lastScrollTop = currentScrollTop;
    logScroll();

});

Barba.js Transitions

I'm also using barba.js with page transitions that all work fine. Every time I load a new page I run a transition and I also run a few of my own custom functions, which have no effect on the scrolling apart from:

$(window).scrollTop(0)

I use to scroll back up to the top of the document. It works cross browser.

var FadeTransition = Barba.BaseTransition.extend({
  start: function() {

    // This function is automatically called as soon the Transition starts
    // this.newContainerLoading is a Promise for the loading of the new container
    // (Barba.js also comes with an handy Promise polyfill!)
    // As soon the loading is finished and the old page is faded out, let's fade the new page

    Promise
      .all([this.newContainerLoading, this.fadeOut()])
      .then(this.fadeIn.bind(this));
  },

  fadeOut: function() {

    // this.oldContainer is the HTMLElement of the old Container
    return $(this.oldContainer).animate({ opacity: 0 }).promise();
  },

  fadeIn: function() {

    // this.newContainer is the HTMLElement of the new Container
    // At this stage newContainer is on the DOM (inside our #barba-container and with visibility: hidden)
    // Please note, newContainer is available just after newContainerLoading is resolved!

    // Custom — Add scrollTop
    $(window).scrollTop(0);
    resetScrollTop();

    // Custom - History ScrollTop
    if ('scrollRestoration' in history) {
      history.scrollRestoration = 'manual';
    }

    var _this = this;
    var $el = $(this.newContainer);

    $(this.oldContainer).hide();

    $el.css({
      visibility : 'visible',
      opacity : 0
    });

    $el.animate({ opacity: 1 }, 400, function() {

    // Do not forget to call .done() as soon your transition is finished!
    // .done() will automatically remove from the DOM the old Container

      _this.done();

    });
  }
});

Reset Scroll

I've also added a custom function that I'm running at the same time to try and reset all of the scrolling.

function resetScrollTop() {
    currentScrollTop    = $(this).scrollTop();
    lastScrollTop       = 0;
    $('nav').removeClass('active');
}

I've even experimented by setting currentScrollTop to zero, which is obviously overwritten on the first scroll, but that doesn't seem to have any effect (and neither does removing the reset function entirely):

currentScrollTop = 0

Console Logs

I've been logging the two values next to each other to try and establish what's going on:

function logScroll() {
  console.log(currentScrollTop + ' ' + lastScrollTop);
}

When I load the first page and scroll down normally currentScrollTop is always at least lastScrollTop + 1:

enter image description here

But after each barba transition, when I scroll down I find that currentScrollTop and lastScrollTop are equal some of the time, which I think is what is causing the problem. I just have no idea what would cause them to increase in sync:

enter image description here

Any help / ideas would be massively appreciated.

1 个答案:

答案 0 :(得分:0)

我最后通过在转换位于resetScrollTop()onEnter时运行onCompleted来解决此问题。

我还将$('.js-nav').addClass('hide')添加到onLeave函数中,该函数将visibility: hidden;添加到.nav元素。

然后我将$('.js-nav').removeClass('hide');添加到函数中的向下滚动条件。

感觉很乱,但似乎可以做到这一点,性能卓越,适用于最新的Chrome,Firefox和Safari。