1
  • Wrapper - Overflow Hidden
    • Div One: Sidebar
    • Div Two: Main Content

Div Two will have a normal scroll. Div One I wish to have no visible scroll however when you scroll Div One it scrolls Div Two.

Upon Div One's height hitting the bottom, it will no longer scroll and visa-versa for scrolling back up.

This will result in the sidebar always being visible at the side. Before you ask, I've tried all positioning types to get this to work resulting in many failed attempts.

My live demo can be seen here: http://rafflebananza.com/admin/newadmin.html#

Note I've tried to make a JSFiddle simplified but my maths does not seem to work in there the same. Please suggest whether I should fork all my page to there or whatnot for future visitors needing the same help.

Overview

Scrolling in the wrapper will scroll sidebar to point x only (x being the sidebars height) then stopping but will continue to allow the content to be scrolled. Visa-versa for scrolling back up.

Somewhat half way there...

var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop,
    position = document.body.scrollTop;

function scrollD() {
    var scroll = document.body.scrollTop;

    if (scroll > position) {
        // Scrolling Down Functions
    } else {
        // Scrolling Up Functions
    }
    position = scroll;
}
Tim Marshall
  • 360
  • 5
  • 25

4 Answers4

1

Updated the answer to match OPs requirements.

I downloaded your website in its current state and made the following changes to your code:

var scrollY = 0;
$(window).scroll(function() {
    var sideNav = $('.SideNav');                // The side navigation
    var wScrollY = $(this).scrollTop();         // Current scroll position of Window
    var navHeight = sideNav.height();           // Height of the Navigation
    var StageHeight = $(window).height() - 46;  // The display space

    if(sideNav.height() > StageHeight) {                    // Do the following if the side navigation is higher than the display space 
        var spaceLeft = sideNav.height() - StageHeight;     // spaceLeft -> how many pixel left before fixing navigation when scrolling

        if(scrollY < wScrollY) {                                // Scroll direction is down
            if (wScrollY >= spaceLeft)                          // If scroll top > space left -> fixate navigation at the bottom, otherwise scroll with the content
                sideNav.css({top:46-spaceLeft+wScrollY});

            if (wScrollY <= 46)                                 // Set top strict to 46. Sometimes there is white space left, caused by the scroll event.       
                sideNav.css({top:46});
        } else {                                                // Scroll direction is up
            var sideNavTop;
            if (sideNav.offset().top < 0) {
                sideNavTop = Math.pow(sideNav.offset().top);    // if top is negative, make it positive for comparison
            } else {
                sideNavTop = sideNav.offset().top;
            }

            if (sideNavTop > (46+wScrollY))                     // Fixate the header if top of navigation appears
                sideNav.css({top:46+wScrollY});
        }
    } else {
        sideNav.css({top:46+wScrollY});                     // Fixate always
    }

    scrollY = wScrollY;
});

This will let you scroll your side navigation up until its end. Then fixate. If you scroll up, it will still be fixated until your reach the point, where the navigation must scrolled back to its original position.

You can check the edited version here: http://pastebin.com/Zkx4pSKe

Just copy the raw code into a blank html page and try it out.

It's a bit messy and maybe not the best solution, but it works.

Tyr
  • 2,810
  • 1
  • 12
  • 21
  • Is there a scroll bottom function? – Tim Marshall Jan 23 '15 at 19:20
  • No. What do you want to achieve? – Tyr Jan 23 '15 at 19:23
  • Both scroll until you reach the bottom of the sidebar then the content just scrolls. Scroll up will scroll both until you reach the top of the sidebar then the content just scrolls. – Tim Marshall Jan 23 '15 at 19:24
  • Basically it's a bit more complicated. You have to check first, in which direction you are scrolling to. Depending on that, you have to check the height of your SideNav to calculate how you have to set the top position. – Tyr Jan 23 '15 at 19:34
  • `SideBarHeight = $('.SideNav').height()` gets the sidebars height after the accordion has resized then `SideBarMax = SideBarHeight + 46;` gets how far the the bottom is from the top of the window. – Tim Marshall Jan 23 '15 at 19:38
  • [This answer](http://stackoverflow.com/questions/4326845/how-can-i-determine-the-direction-of-a-jquery-scroll-event) helps detect the direction of the scroll too :) – Tim Marshall Jan 23 '15 at 19:45
  • Updated my live version, could you please check it and provide any feedback? Click on the last menu category then scroll down. – Tim Marshall Jan 23 '15 at 20:43
  • Thumbs up! Working on way now to figure out the reverse (without needing to scroll to top to see top of menu) – Tim Marshall Jan 23 '15 at 21:36
  • 1
    Updated again, it works now even for reverse scrolling – Tyr Jan 23 '15 at 21:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/69498/discussion-between-tim-marshall-and-tyr). – Tim Marshall Jan 24 '15 at 09:21
1

Ok, here you go:

var $sidebar = $('.sidebar'),
    $window = $(window),
    previousScroll = 0;
$window.on('scroll', function (e) {
    if ($window.scrollTop() - previousScroll > 0) {
        $sidebar.css({
            'top': Math.max($window.scrollTop() + $window.height() - $sidebar.outerHeight(true), parseInt($sidebar.css('top'))) + 'px'
        });
    } else {
        $sidebar.css({
            'top': Math.min($window.scrollTop(), parseInt($sidebar.css('top'))) + 'px'
        });
    }
    previousScroll = $window.scrollTop();
});

http://jsfiddle.net/7nwzcpqk/1/

glyuck
  • 3,367
  • 18
  • 14
  • Nice but works one way only sorry. [Tyr's answer](http://stackoverflow.com/a/28117082/4423554) is similar but one way only. Almost there, going to try and figure out the scrolling up part to make them scroll the same until it reaches the top of the sidebar. – Tim Marshall Jan 23 '15 at 21:41
  • Thumbs up by the way :) – Tim Marshall Jan 23 '15 at 21:47
0

i might have misunderstood your desired result incorrectly but you can see if this works for you :

.SideNav {
   position: fixed; // you currently have this as position:absolute;
}
indubitablee
  • 8,136
  • 2
  • 25
  • 49
0

You don't need nor a wrapper element nor jQuery. I assume that you are using a wrapper because you want to have the top bar placed there. I think there is a better way to do it by using simply three divs.

  • The top bar has to be fixed (to be always visible) and of full width.
  • The side bar also has to be fixed (to be always visible) with a top margin of the height of the top bar.
  • The content needs just a left padding (width of side bar) and top padding (height of top bar).

Here is the example code (http://jsfiddle.net/zckfwL4p/):

HTML

<div id="top_bar"></div>
<div id="side_bar">links here</div>
<div id="content"></div>

CSS

body {
    margin:0px;
    padding:0px;
}

#side_bar {
    width:50px;
    position: fixed;
    left:0px;
    top:20px;
    background-color:blue;
}

#top_bar {
    position:fixed;
    height:20px;
    left:0px;
    right:0px;
    background-color:red;
}

#content {
    position:relative;
    padding-left:55px;
    padding-top:25px;
}
Guillermo
  • 764
  • 6
  • 15