使用jQuery检测滚动方向的变化

时间:2016-02-25 13:57:58

标签: javascript jquery css scroll

我正在使用基本的jQuery函数在向上或向下滚动时将某些类切换为div。

基本上它的工作原理如下:

  • 当用户向下滚动时,添加“is-header-hidden”类,删除“is-header-visible”类
  • 当用户向上滚动时,添加“is-header-visible”类,删除“is-header-hidden”类

这是我的代码:

function hidingHeader() {

    var didScroll,
        lastScrollTop = 0,
        tolerance = 15,
        header = $('header'),
        headerHeight = header.outerHeight(true),
        fixedClass = ('is-header-fixed'),
        hiddenClass = ('is-header-hidden'),
        visibleClass = ('is-header-visible'),
        transitioningClass = ('is-header-transitioning');

    win.scroll(function( event ) {
        didScroll = true;
    });

    setInterval(function() {
        if ( didScroll ) {
            hasScrolled();
            didScroll = false;
        }
    }, 250);

    function hasScrolled() {
        var st = $(this).scrollTop();

        // SCROLL DOWN
        if( st > lastScrollTop ) {

            header.removeClass( visibleClass );
            if( st >= headerHeight ) {
                header.addClass( fixedClass ).addClass( hiddenClass );
            }

        // SCROLL UP
        } else {
            // Make sure they scroll more than tolerance
            if( Math.abs( lastScrollTop - st ) > tolerance ) {
                header.removeClass( hiddenClass ).addClass( visibleClass );
            }
        }

        // UPDATE SCROLL VAR
        var lastScrollTop = st;
    }
}

现在,我想添加一个包含CSS transform属性的“is-transitioning”类,我将使用CSS animation callback删除它。问题是我需要该类触发一次,换句话说,只有在滚动方向发生变化时,而不是每次用户滚动时。

我想存储一个“倒数第二个”的scrollTop变量,以便检测滚动方向何时发生变化,但我的尝试失败了。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

也许是这样的?

function hidingHeader() {

var didScroll,
    lastScrollTop = 0,
    tolerance = 15,
    lastDir = null,  // you can start with a non-null if you don't want to trigger the first down for example, make this lastDir = "down",
    header = $('header'),
    headerHeight = header.outerHeight(true),
    fixedClass = ('is-header-fixed'),
    hiddenClass = ('is-header-hidden'),
    visibleClass = ('is-header-visible'),
    transitioningClass = ('is-header-transitioning');

win.scroll(function( event ) {
    didScroll = true;
});

setInterval(function() {
    if ( didScroll ) {
        hasScrolled();
        didScroll = false;
    }
}, 250);

function hasScrolled() {
    var st = $(this).scrollTop();

    // SCROLL DOWN
    if( st > lastScrollTop ) {

        header.removeClass( visibleClass );
        if( st >= headerHeight ) {
            header.addClass( fixedClass ).addClass( hiddenClass );
        }

        if( lastDir !== "down" ) { // Should only get triggered once while scrolling down, the first time the direction change happens
            lastDir = "down";
            // do your transition stuff here
        }

    // SCROLL UP
    } else {
        // Make sure they scroll more than tolerance
        if( Math.abs( lastScrollTop - st ) > tolerance ) {
            header.removeClass( hiddenClass ).addClass( visibleClass );
        }

        if( lastDir !== "up" ) { // Should only get triggered once while scrolling up, the first time the direction change happens
            lastDir = "up";
            // do your transition stuff here
        }
    }

    // UPDATE SCROLL VAR
    var lastScrollTop = st;
}

}