Calculating Height of Sidebar Dynamically

1.7k views Asked by At

I'm trying to work out the algorithm for a fixed div that grows in height (while scrolling) until it's equal to the height of the viewport or div with fixed position relative to another div and the bottom of the viewport

I am using Twitter Bootstrap affix to lock my secondary navigation bar (yellow) and my sidebar (black) to the top of the screen when the user scrolls that far.  This works fine. The sidebar is the piece that's giving me trouble.  When it is in its in its starting position (as shown in the diagram belorw), I want the top of the bar to sit 30px down from the secondary navigation bar (yellow) and 30px up from the bottom of the page. 

enter image description here

As the user scrolls, the bar should grow in height so that it remains 30px beneath the secondary navigation bar and 30px above the bottom of the screen (As shown in the diagram below)

enter image description here

After the bar is fixed position, I am able to do what I need to do.  

.sidebar { 
position:fixed;
top:100px;  
bottom:30px;
left:30px;
}

What I can't figure out is how to position the TOP of the sidebar relative to my secondary navigation bar and the BOTTOM of my sidebar relative to the bottom of the screen. I've tried calculating the height of the sidebar at the beginning and the end of the scroll but this causes issues.

I've also tried calculating the final height of the sidebar and letting the bottom of the sidebar just run off the edge of the screen (when it's in its initial position), but if there's not enough content on the right side to warrant scrolling, I have no way of getting to the bottom items in the scroll bar.  Plus my screen starts bouncing in a really un­attractive way.

below is the current code in use:

ShelvesSideBar.prototype._resize_sidebar = function(_this) {
    var PADDING = 50;
    var window_height = $(window).height(),
        nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
        sidebar_height = window_height - nav_bar_height - PADDING,
        sidebar_scrollable_height = sidebar_height - $('.bar_top').height();

    _this.$container.height(sidebar_height);
    _this.$container.find('.bar_bottom').height(sidebar_scrollable_height);

    /* reset the nanoscroller */
    _this.$container.nanoScroller();
};

    this code is called on page load and again on window resize. Any help would be greatly appreciated!

2

There are 2 answers

0
Bobby On BEST ANSWER

so I was able to figure this out, for anyone still looking. What I ended up doing was binding to the window scroll event and - whenever the scroll occurred - I check if the class "affix" has been added to the sidebar. If it has, then I perform one set of calculations to determine sidebar height. Otherwise, I perform the other set of calculations. Code below:

/* called on window scroll */
var PADDING = 70;

var window_height = $(window).height(),
    nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
    header_height = $('.prof_block').height() - nav_bar_height,
    sidebar_height = _this.$container.hasClass("affix") ? window_height - nav_bar_height - PADDING : window_height - (header_height + nav_bar_height) - PADDING,
    sidebar_scrollable_height = sidebar_height - $('.bar_top').height();

_this.$container.height(sidebar_height);
_this.$container.find('.bar_bottom').height(sidebar_scrollable_height);
2
azariah On

I've been trying to do something similar (minus the fixed elements and navbars). What I found was in order to do any sort of relative height scaling every element above the element I wished to scale all the way up to the opening html tags had to have a relative height set, even if it was just height:100%;. (here's my original question Variable height, scrollable div, contents floating)

My goal was to have the body height fixed to window size like a native full screen application would be with my content subareas scrolling, so this is a bit off topic for what you're wanting to accomplish. But I tried using JS/JQ to start off with as you're trying to do currently and found that I simply couldn't get the window height because the default behaviour for height management is to expand the page height until everything on the page fits. And all the getHeight methods I tried we're getting the page height not window/viewport height as promised. So you may wish to try fixing your body's height to the window and going from there using overflow:scroll; to scroll the page.

A quick note on overflow:scroll; if you have users who use WP8 IE (and probably other versions of IE) it may be advantageous to implement FTscroller to handle all your scroll elements as the overflow property defaults to hidden and is a fixed browser property. The only problem with FTscroller is because it uses CSS offsets to move the content container it may wreak havoc on elements that are designed to switched to fix when they reach x height from top of page because technically the top of page (or rather the top of the container they're in) isn't at the top of the page anymore it's beyond it. Just something to be aware of if you do need to cater for this browser.

And apologies for the complexity of my sentence structure. :/