高级jQuery固定边栏

10

我正在开发一个(固定的)滚动侧边栏。问题是大多数固定的侧边栏没有考虑到侧边栏可能高于视口(例如,如果向购物篮(侧边栏)添加了许多项目)。这就是我要解决的问题。以下是需求:

  • 如果侧边栏的高度比视口高,则应该通过内容滚动,并且在向下滚动时,div 底部应粘着在视口底部。

  • 如果侧边栏的高度比视口高,则只有当您在页面底部时才应显示其下面的 div。

  • 当用户向上滚动时,侧边栏会滚动回顶部并重新粘贴到视口顶部。

  • 如果侧边栏的高度小于视口,则在向下滚动时应从顶部粘着。

总体来说,这是相当复杂的功能,不那么简单(我认为)。我看到的最接近我要实现的效果是这个示例:http://demo.techbrij.com/730/fix-sidebar-scrolling-jquery.php,但是代码编写方式与我的不符。

至此,我已经做了如下的内容:DEMO

以下是我使用的jQuery代码:

jQuery(document).ready(function($) {

var $sidebar   = $('.sidebar'),
    $content   = $('.content');

if ($sidebar.length > 0 && $content.length > 0) {
    var $window    = $(window),
        offset     = $sidebar.offset(),
        timer;

    $window.scroll(function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            if ($content.height() > $sidebar.height()) {
                var new_margin = $window.scrollTop() - offset.top;
                if ($window.scrollTop() > offset.top && ($sidebar.height()+new_margin) <= $content.height()) {
                    // Following the scroll...
                    $sidebar.stop().animate({ marginTop: new_margin });
                } else if (($sidebar.height()+new_margin) > $content.height()) {
                    // Reached the bottom...
                    $sidebar.stop().animate({ marginTop: $content.height()-$sidebar.height() });
                } else if ($window.scrollTop() <= offset.top) {
                    // Initial position...
                    $sidebar.stop().animate({ marginTop: 0 });
                }
            }
        }, 100); 
    });
}

});

嗯,我没有考虑到这一点,对于我的粘性标题/元素库。我想我有一个新的问题要解决。 :-) http://underpull.github.com/Balloon/ - Vinay
3个回答

3

您正在使用边距来移动粘性侧边栏 - 我发现这是处理您当前要求的一种棘手方式(并且可能是较重的方式)。

通常情况下,我喜欢简单地向侧边栏添加一个类,使其成为“position:fixed”,这样浏览器就会在保持其锁定方面承担更多的工作。

对于您当前的要求,您只需要以编程方式滚动该位置固定的div(也使其100%高度),具体取决于他们已经滚动的距离。看看我的示例,看看这是否是您想要的效果:http://jsfiddle.net/ZHP52/1/

这是jquery代码:

jQuery(document).ready(function($) {

var $sidebar   = $('.sidebar'),
    $content   = $('.content');

//Since our CSS is going to monkey with the height as you scroll, I need to know the initial height.
var sidebarHeight = $sidebar.height();

if ($sidebar.length > 0 && $content.length > 0) {
    var $window    = $(window),
        offset     = $sidebar.offset(),
        timer;

    $window.scroll(function() {

        if ($content.height() > sidebarHeight) {
            var new_margin = $window.scrollTop() - offset.top;
            if ($window.scrollTop() > offset.top) {
                // Fix sidebar
                $sidebar.addClass("fixed");
                // Scroll it the appropriate ammount
                $sidebar.scrollTop(new_margin);            
            }else{
                $sidebar.removeClass("fixed");
            }
        }
    });
}

});

抱歉回复晚了,刚看到您的信息。我认为您的js fiddle有点小bug,从代码中可以看出它没有实现以下要求之一:如果侧边栏的高度比视口更高,则应滚动内容并在向下滚动时将div底部固定在视口底部。 - Yunowork
啊,抱歉 - 我的快速样式取决于浏览器大小。不过我认为我的答案仍然适用 - 滚动时触发类来切换导航栏到固定位置,并根据你计算的滚动偏移量实现侧边栏内容的实际滚动。 - gcoladarci

1

看看hcSticky,我刚刚找到了它。这是一种“完美”的粘性侧边栏,还可以通过选项模拟其他库。

第一个演示可能是每个人都需要的,它将容器与主要内容分开滚动。(在到达页面底部之前,您可以浏览整个侧边栏,或者在向上滚动滚动条时到达页面顶部之前)。

查看链接:http://someweblog.com/demo/hcsticky/


最好的库,我试过了,谢谢! https://github.com/somewebmedia/hc-sticky - Jibato

0

我相信这是您正在寻找的功能:http://jsfiddle.net/JVe8T/7/

对于代码的混乱,我感到抱歉,但优化它应该相当容易。我还假设sidebar2(非粘性的那个)已经定义了高度,如果不是这种情况,您可以使用jquery检测它并使用.css选择器进行底部偏移。

这是我的代码:

jQuery(document).ready(function() {

    var tmpWindow = $(window),
        sidebar = $('.sidebar'),
        content = $('.content'),
        sidebar1 = $('.sidebar1'),
        sidebar2 = $('.sidebar2'),
        viewportHeight = $(window).height(),
        sidebarHeight = sidebar.height(),
        sidebar1Height = sidebar1.height(),
        sidebar2Height = sidebar2.height(),
        offsetBottom;


    tmpWindow.scroll(function(){

        offsetBottom = content.height() - sidebar2Height;

        //if sidebar height is less that viewport
        if (viewportHeight > sidebarHeight) {
            sidebar.addClass('fixed');
        } 

        //sticky sidebar1
        if ((tmpWindow.scrollTop() + viewportHeight) > sidebar1Height ) {
            sidebar1.addClass('bottom');
        } else {
            sidebar1.removeClass('bottom');
        }

        //end of content, visible sidebar2
        if ((tmpWindow.scrollTop() + viewportHeight) > offsetBottom) {
            sidebar1.removeClass('bottom');
            sidebar1.addClass('fixedBottom');
        } else {
            sidebar1.removeClass('fixedBottom');
        }

    });

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接