frFixedHeader.js 2.09 KB
/**
 * A directive that will invoke a sticky header upon scroll.
 *
 * This directive is strongly coupled with the markup and design of the
 * header.
 *
 * A "mini" variation of the header will be made sticky if all of the following
 * conditions are met:
 *
 * - Window is scrolled under the element with this directive.
 * - Window is being scrolled up at the minimum rate of 10px per arbitrary unit
 *   of time (debounce).
 *
 * This header will be hidden when one of the following conditions is met:
 *
 * - Window is scrolled down at a minimum rate of 5px per arbitrary unit of
 *   time (debounce).
 * - Window is scrolled to the top.
 */

angular.module('fr.fixedHeader', [])

.directive('frFixedHeader', ['$window', function ($window) {
    return {
        restrict: 'A',
        link: function (scope, element) {
            var

                windowEl 		= angular.element($window),
                headerEl 		= $('.sidebar'),

                lastScrollTop	= 0,
                scrollTop 		= 0,
                fixed			= false,
                minTopOffset    = 10; // Minimum scroll that is required to show the mini header.

            // Attach scroll up anchor click event on the mini header.
            $('.up-anchor').click(function () {
                $('html, body').animate({ scrollTop: 0 }, 100);
            });

            // Register the scroll event.
            windowEl.on('scroll', function (e) {
                scrollTop = windowEl.scrollTop();

                // Scroll down.
                if (lastScrollTop < scrollTop && scrollTop - lastScrollTop > 5 || scrollTop < minTopOffset) {
                    if (fixed) {
                        headerEl.removeClass('mini-visible');
                        fixed = false;
                    }
                }
                // Scroll up, under site-tree.
                else if (!fixed && lastScrollTop - scrollTop > 10 && scrollTop > element.offset().top) {
                    headerEl.addClass('mini-visible');
                    fixed = true;
                }

                lastScrollTop = scrollTop;
            });
        },
    };
}]);