简体   繁体   English

高级jQuery粘贴侧边栏

[英]Advanced jQuery sticky sidebar

I'm working on a (sticky) scrolling sidebar. 我正在使用(粘性)滚动侧边栏。 The problem is that most sticky sidebars don't take into consideration that the sidebar can be taller then the viewport (eg if many items are added to the basket(sidebar)). 问题是大多数粘性侧边栏没有考虑边栏可能比视口高(例如,如果很多项目被添加到篮子(侧边栏))。 Which is what I'm trying to solve. 这就是我想要解决的问题。 These are the requirements: 这些是要求:

  • If the height of the sidebar is taller then the viewport, it should scroll through the content and the bottom of the div should stick to the bottom of the viewport when scrolling further down. 如果侧边栏的高度比视口高,则应滚动内容,并且当向下滚动时,div的底部应粘贴到视口的底部。

  • If the height of the sidebar is taller then the viewport, the divs underneath should only be shown when you are at the bottom of the page. 如果侧边栏的高度比视口高,则只有当您位于页面底部时才会显示下面的div。

  • When user scrolls back up, the sidebar scrolls back to the top and sticks back onto the top of the viewport. 当用户向上滚动时,侧边栏会向后滚动到顶部并回到视口的顶部。

  • If the height of the sidebar is less then the viewport, it should be sticky from the top on when scrolling down. 如果侧边栏的高度小于视口,则向下滚动时顶部应该是粘性的。

So all in all quite some functionality and not that simple (I think). 总而言之,相当一些功能而不是那么简单(我认为)。 The closest I've seen to what I'm trying to achieve is this example: http://demo.techbrij.com/730/fix-sidebar-scrolling-jquery.php but the way the code is written doesn't fit into mine. 我见过的最接近我想要实现的是这个例子: http//demo.techbrij.com/730/fix-sidebar-scrolling-jquery.php但是编写代码的方式不合适进入我的。

So far, this is what I've made: DEMO 到目前为止,这就是我所做的: DEMO

And the jQuery code I used: 我使用的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); 
    });
}

});

You are using margins to move the sticky sidebar around - I've found this to be a tricky way to handle your current ask (and potentially a heavier way). 你正在使用边距来移动粘性侧边栏 - 我发现这是处理当前问题的一种棘手的方法(并且可能是更重的方式)。

In general, I like to simply add a class to the sidebar that makes it be "position: fixed" so the browser does the heavy lifting on keeping it locked. 一般来说,我喜欢简单地在侧边栏中添加一个类,使其成为“position:fixed”,这样浏览器就可以保持锁定状态。

For your current ask, you simply have to scroll that position fixed div (which is also made 100% height) programmatically based on how far down they have scrolled. 对于您当前的问题,您只需要根据它们滚动的距离以编程方式滚动该位置固定div(也是100%高度)。 Take a look at my example and see if this is the effect you are after: http://jsfiddle.net/ZHP52/1/ 看看我的例子,看看这是否是你所追求的效果: http//jsfiddle.net/ZHP52/1/

here's the jquery: 这是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");
            }
        }
    });
}

});

I belive this is functionality you are looking for: http://jsfiddle.net/JVe8T/7/ 我相信这是你正在寻找的功能: http//jsfiddle.net/JVe8T/7/

Sorry for messy code but it should be fairly easy to optimize it. 对不起凌乱的代码,但优化它应该相当容易。 I also assumed that sidebar2 (the non-sticky one) has defined height, if that is not the case you could just detect it with jquery and use .css selector for bottom offset. 我还假设sidebar2(非粘性的)已经定义了高度,如果不是这种情况你可以用jquery检测它并使用.css选择器进行底部偏移。

Here's my code: 这是我的代码:

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');
        }

    });

});

Check out hcSticky, I was just looking for this. 看看hcSticky,我只是在找这个。 It's kind of the "perfect" sticky sidebar and can also emulate the other libraries with options. 它是一种“完美”的粘性侧边栏,也可以通过选项模拟其他库。

The first demo is probably what everyone needs, it scrolls a container independently from the main content. 第一个演示可能是每个人都需要的,它独立于主要内容滚动容器。 (you can go through the whole sidebar before reaching the bottom of the page or when you scroll bar up, before reaching the top of the page). (您可以在到达页面底部之前浏览整个侧边栏,或者在到达页面顶部之前向上滚动条形图)。

Check it out: http://someweblog.com/demo/hcsticky/ 看看: http//someweblog.com/demo/hcsticky/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM