Edit in JSFiddle

function follow_scroll_smoothly(elementSelector, footerSelector) {
  var element = $(elementSelector);
  var elementHeight = element.outerHeight();
  var windowHeight = $(window).height();
  var documentHeight = $(document).height();
  var headerMinimumTop = element.offset().top;
  var footerMaximumTop = documentHeight;
  if (footerSelector && $(footerSelector).length) {
    footerMaximumTop = documentHeight - $(footerSelector).outerHeight();
  }
  console.log("follow_scroll_smoothly headerMinimumTop=" + headerMinimumTop);

  // Space between element and top/bottom of screen (when scrolling)
  var topMargin = 5;
  var bottomMargin = 15;

  // Should probably be set in CSS; but here just for emphasis
  element.css('position', 'relative');

  function checkRangeRelativeTop(relativeTop) {
    var result = relativeTop;
    if (result < 0) {
      // can not go above initial position
      result = 0;
    } else if (result > footerMaximumTop - elementHeight - headerMinimumTop) {
      // can not go bewond footer
      result = footerMaximumTop - elementHeight - headerMinimumTop;
    }
    return result;
  }

  function stickTop(scrollTop) {
    var newRelativeTop = checkRangeRelativeTop(scrollTop - headerMinimumTop + topMargin);
    element.stop(false, false).animate({
        top: newRelativeTop,
    }, 300);
    $('#debug').prepend('<br>stickTop ' + newRelativeTop);
  }
  function stickBottom(scrollTop) {
    // we don't use animate bottom since it is relative to element, we use top
    var newRelativeTop = checkRangeRelativeTop(scrollTop - headerMinimumTop + windowHeight - elementHeight - bottomMargin);

    element.stop(false, false).animate({
        top: newRelativeTop,
    }, 300);
    $('#debug').prepend('<br>stickBottom ' + newRelativeTop);
  }
  var lastScrollTop = 0;
  $(window).on('scroll', function(event) {
    // get the vertical position of scrollbar
    var scrollTop = $(window).scrollTop();
    var scrollDownDirection = scrollTop > lastScrollTop;
    lastScrollTop = scrollTop;
    var elementTop = element.offset().top
    var elementBottom = elementTop + elementHeight;
    var weSeeBottom = windowHeight + scrollTop > elementBottom && scrollTop < elementBottom;
    var weSeeTop = windowHeight + scrollTop > elementTop && scrollTop < elementTop;
    $('#info').html(JSON.stringify(
      {
        windowHeight: windowHeight,
        headerMinimumTop: headerMinimumTop,
        elementHeight: elementHeight,
        elementTop: elementTop,
        footerMaximumTop: footerMaximumTop,
        // scrollTop: scrollTop,
        // weSeeBottom: weSeeBottom,
        // weSeeTop: weSeeTop,
        // scrollDownDirection: scrollDownDirection,
      }
    ));

    if (scrollDownDirection && weSeeBottom && !weSeeTop)
    {
      if (windowHeight > elementHeight) {
        // we see whole element
        stickTop(scrollTop);
      } else {
        // we don't whole element because top is out of page
        stickBottom(scrollTop);
      }
    }
    else if (!scrollDownDirection && !weSeeBottom && weSeeTop)
    {
      if (windowHeight > elementHeight) {
        stickBottom(scrollTop);
      } else {
        stickTop(scrollTop);
      }
    }
    else if (!weSeeBottom && !weSeeTop && (elementBottom < scrollTop || elementTop > scrollTop + windowHeight))
    {
      if (scrollDownDirection) {
        stickTop(scrollTop);
      } else {
        stickBottom(scrollTop);
      }
    }
  });
}
$(function() { follow_scroll_smoothly('.sidebar','.footer');
  follow_scroll_smoothly('.big-sidebar','.footer');
});
<div style="position: fixed; top:10px;right:50px;z-index=99999999;background-color: white;" id="info"></div>
<div style="position: fixed; top:30px;right:50px;z-index=999;background-color: white;" id="debug"></div>
<h1 class="header">
  Header
</h1>
<div class="main">
  <div class="sidebar">
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>
  </div>
  <div class="content">
    <p>Try to scroll to see how
    <br>
    <span style="background-color:yellow">small sidebar</span>
    and
    <span style="background-color:blue">big sidebar</span>
    follows you.
    </p>
    <p class="big-paragraph">Paragraph 1</p>
    <p class="big-paragraph">Paragraph 2</p>
    <p class="big-paragraph">Paragraph 3</p>
  </div>
  <div class="big-sidebar">
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>
  </div>
</div>
<footer class="footer">
  Some footer
</footer>
.sidebar {
  float: left;
  background: yellow;
}
.big-sidebar {
  float: right;
  background: blue;

}
.big-sidebar li {
    padding-top: 200px;   
  }
.content {
  float: left;
  padding: 10px;
}

.main::after {
  content: "";
  display: table;
  clear: both;
}
.big-paragraph {
  padding-top: 300px;
}

.header,
.footer {
  text-align: center;
}

External resources loaded into this fiddle: