I implemented an automatic subnav dashboard, taken directly from Bootstrap docs CSS and JS , on the site I'm working on. It is displayed in only one view, but it is a Rails view, so it is dynamically generated depending on which object is loaded.
What I found is that when the content that appears under the subnav line is long enough, the behavior of the subnav bar works as expected - the subnav-based class is added right when the subnav bar is scrolled out field of view.
If the page is smaller than this, however, the subnav panel will become fixed before it is out of sight, which creates a rather sharp jump, not to mention that you can see the space in which there was a panel that you should not see .
I have to add that I am using a fixed (main) navigation bar with appropriate consideration for body filling.
It seems that the problem is with the return value of $('.subnav').offset.top
.
Can someone better with jQuery / JS help diagnose this, and come up with a way to make the subnav panel only fixed when it scrolls out of sight?
Javascript:
var $win = $(window) , $nav = $('.subnav') , navTop = $('.subnav').length && $('.subnav').offset().top , isFixed = 0 , $hiddenName = $('.subnav .hide') processScroll() $nav.on('click', function () { if (!isFixed) setTimeout(function () { $win.scrollTop($win.scrollTop() - 47) }, 10) }) $win.on('scroll', processScroll) function processScroll() { var i, scrollTop = $win.scrollTop() if (scrollTop >= navTop && !isFixed) { isFixed = 1 $nav.addClass('subnav-fixed') $hiddenName.removeClass('hide') if (!$('.subnav li').hasClass('active')) { $('.subnav li:eq(1)').addClass('active') } } else if (scrollTop <= navTop && isFixed) { isFixed = 0 $nav.removeClass('subnav-fixed') $hiddenName.addClass('hide') $('.subnav li').removeClass('active') } }
Replicating Bootstraps main nav and subnav - I saw this question, but I don't think it escapes the problem as it still uses .offset()
UPDATE:
Still out of luck. navTop
still seems shorter as the page length gets shorter, which makes no sense since it uses offset().top
. Is there anything about how this method works that I don't get?
UPDATE 2
It seems like this can be resolved with Bootstrap 2.1.0, as it will actually include a subnav panel as a real component, as well as a jQuery plugin for managing sticky behavior. However, I would like to understand why the offset () function is so unreliable.