views:

572

answers:

2

I have a sidebar that I want to behave like it's frozen on the right side of the pane even when the scroll bar moves the down to see more content. I gave up on it being perfectly fixed and handled it by the sidebar scrolling down with the page using jQuery. Currently this is how I'm handling this.

<script type="text/javascript">
$(window).scroll(function() {
    $('#sidebarPage1').animate(
        { top: $(window).scrollTop() + 'px' }, 
        { queue: false, duration: 500, easing: 'easeInOutSine' }
    );
});
</script>

I have a 100% wide header and footer on my page so the top of the sidebar is offset by about 150px from the top, when users have small viewports when they scroll entirely to the bottom the bar will end up going under my footer or if it's a really small view port entirely off the screen.

Would there be an easy way to calculate what to set top at, to have it stop approximately 200px from the bottom of the viewport so it doesn't crash through the footer?

Updated from Joel's answer:

<script type="text/javascript">
    $(window).scroll(function() {            
        var dynamicSidebarHeight = $('#sidebar').height();            
        var fixedFooterOffset = 168;
        var scrollTo = $(window).scrollTop()
        var calculatedMaxTop = $('#footer').offset().top - 
                    dynamicSidebarHeight - fixedFooterOffset;

        if (scrollTo > calculatedMaxTop) {
            scrollTo = calculatedMaxTop;
        }
        $('#sidebarPage1')
            .animate(
                { top: scrollTo + 'px' },
                { queue: false, duration: 500, easing: 'easeInOutSine' }
        );
    });
</script>

Fixed .Height() function

+1  A: 

Maybe use the top of the footer?

$(window).scroll(function() {
    var scrollTo = $(window).scrollTop()
    if (scrollTo > ($("#footer").offset().top - 200))
        scrollTo = $("#footer").offset().top - 200;

    $('#sidebarPage1').animate(
        { top: scrollTo + 'px' }, 
        { queue: false, duration: 500, easing: 'easeInOutSine' }
    );
});

Untested. You may have to do some parseInt's to get this to work.

Joel Potter
Thanks Joel your answer gave me almost everything I needed to work with! The Offset() function was really what this whole question was about, I knew what I needed but not how to get there. The only thing you had backwards is that you need to subtract the values from tops.
Chris Marisic
Yup, your right. I got the comparison right, but forgot the addition/subtraction. Editing now.
Joel Potter
A: 

I wrote a blog post on how to polish this effect up and in more depth on how this solution was created: Using jQuery to create a scrolling sidebar.

Chris Marisic