Sticky sidebar: stick to bottom when scrolling down, top when scrolling up

前端 未结 6 2012
遥遥无期
遥遥无期 2020-12-07 08:28

I have been looking for some time now for a solution to my sticky sidebar problem. I have a specific idea of how I would like it to act; effectively, I would like it to stic

6条回答
  •  青春惊慌失措
    2020-12-07 09:12

    Here's an example of how to implement this:

    JavaScript:

    $(function() {
    
    var $window = $(window);
    var lastScrollTop = $window.scrollTop();
    var wasScrollingDown = true;
    
    var $sidebar = $("#sidebar");
    if ($sidebar.length > 0) {
    
        var initialSidebarTop = $sidebar.position().top;
    
        $window.scroll(function(event) {
    
            var windowHeight = $window.height();
            var sidebarHeight = $sidebar.outerHeight();
    
            var scrollTop = $window.scrollTop();
            var scrollBottom = scrollTop + windowHeight;
    
            var sidebarTop = $sidebar.position().top;
            var sidebarBottom = sidebarTop + sidebarHeight;
    
            var heightDelta = Math.abs(windowHeight - sidebarHeight);
            var scrollDelta = lastScrollTop - scrollTop;
    
            var isScrollingDown = (scrollTop > lastScrollTop);
            var isWindowLarger = (windowHeight > sidebarHeight);
    
            if ((isWindowLarger && scrollTop > initialSidebarTop) || (!isWindowLarger && scrollTop > initialSidebarTop + heightDelta)) {
                $sidebar.addClass('fixed');
            } else if (!isScrollingDown && scrollTop <= initialSidebarTop) {
                $sidebar.removeClass('fixed');
            }
    
            var dragBottomDown = (sidebarBottom <= scrollBottom && isScrollingDown);
            var dragTopUp = (sidebarTop >= scrollTop && !isScrollingDown);
    
            if (dragBottomDown) {
                if (isWindowLarger) {
                    $sidebar.css('top', 0);
                } else {
                    $sidebar.css('top', -heightDelta);
                }
            } else if (dragTopUp) {
                $sidebar.css('top', 0);
            } else if ($sidebar.hasClass('fixed')) {
                var currentTop = parseInt($sidebar.css('top'), 10);
    
                var minTop = -heightDelta;
                var scrolledTop = currentTop + scrollDelta;
    
                var isPageAtBottom = (scrollTop + windowHeight >= $(document).height());
                var newTop = (isPageAtBottom) ? minTop : scrolledTop;
    
                $sidebar.css('top', newTop);
            }
    
            lastScrollTop = scrollTop;
            wasScrollingDown = isScrollingDown;
        });
    }
    });
    

    CSS:

    #sidebar {
      width: 180px;
      padding: 10px;
      background: red;
      float: right;
    }
    
    .fixed {
      position: fixed;
      right: 50%;
      margin-right: -50%;
    }
    

    Demo: http://jsfiddle.net/ryanmaxwell/25QaE/

    This works as expected in all scenarios and is well-supported in IE too.

提交回复
热议问题