docs: function calculateFloatContainerPosFn(){
          var scrollingContainerTop = $scrollContainer.scrollTop();
  
          //this floatEnd calc was moved out of the returned function because we assume the table height doesn't change (otherwise we must reinit by calling calculateFloatContainerPosFn)
          var floatEnd;
          var tableContainerGap = 0;
          var captionHeight = haveCaption ? $caption.outerHeight(true) : 0;
          var captionScrollOffset = captionAlignTop ? captionHeight : -captionHeight;
  
          var floatContainerHeight = $floatContainer.height();
          var tableOffset = $table.offset();
          var tableLeftGap = 0; //can be caused by border on container (only in locked mode)
          var tableTopGap = 0;
          if(locked){
            var containerOffset = $scrollContainer.offset();
            tableContainerGap = tableOffset.top - containerOffset.top + scrollingContainerTop;
            if(haveCaption && captionAlignTop){
              tableContainerGap += captionHeight;
            }
            tableLeftGap = floatContainerBorderWidth('left');
            tableTopGap = floatContainerBorderWidth('top');
            tableContainerGap -= tableTopGap;
          } else {
            floatEnd = tableOffset.top - scrollingTop - floatContainerHeight + scrollingBottom + scrollbarOffset.horizontal;
          }
          var windowTop = $window.scrollTop();
          var windowLeft = $window.scrollLeft();
          var getScrollContainerLeft = function(){
            return (isResponsiveContainerActive() ?  $responsiveContainer : $scrollContainer).scrollLeft() || 0;
          };
          var scrollContainerLeft = getScrollContainerLeft();
  
          return function(eventType){
            responsive = isResponsiveContainerActive();
  
            var isTableHidden = $table[0].offsetWidth <= 0 && $table[0].offsetHeight <= 0;
            if(!isTableHidden && floatTableHidden) {
              floatTableHidden = false;
              setTimeout(function(){
                $table.triggerHandler("reflow");
              }, 1);
              return null;
            }
            if(isTableHidden){ //it's hidden
              floatTableHidden = true;
              if(!useAbsolutePositioning){
                return null;
              }
            }
  
            if(eventType == 'windowScroll'){
              windowTop = $window.scrollTop();
              windowLeft = $window.scrollLeft();
            } else if(eventType == 'containerScroll'){
              if($responsiveContainer.length){
                if(!responsive){
                  return; //we dont care about the event if we arent responsive right now
                }
                scrollContainerLeft = $responsiveContainer.scrollLeft();
              } else {
                scrollingContainerTop = $scrollContainer.scrollTop();
                scrollContainerLeft = $scrollContainer.scrollLeft();
              }
            } else if(eventType != 'init') {
              windowTop = $window.scrollTop();
              windowLeft = $window.scrollLeft();
              scrollingContainerTop = $scrollContainer.scrollTop();
              scrollContainerLeft =  getScrollContainerLeft();
            }
            if(isWebkit && (windowTop < 0 || windowLeft < 0)){ //chrome overscroll effect at the top of the page - breaks fixed positioned floated headers
              return;
            }
  
            if(absoluteToFixedOnScroll){
              if(eventType == 'windowScrollDone'){
                changePositioning(true); //change to absolute
              } else {
                changePositioning(false); //change to fixed
              }
            } else if(eventType == 'windowScrollDone'){
              return null; //event is fired when they stop scrolling. ignore it if not 'absoluteToFixedOnScroll'
            }
  
            tableOffset = $table.offset();
            if(haveCaption && captionAlignTop){
              tableOffset.top += captionHeight;
            }
            var top, left;
            var tableHeight = $table.outerHeight();
  
            if(locked && useAbsolutePositioning){ //inner scrolling, absolute positioning
              if (tableContainerGap >= scrollingContainerTop) {
                var gap = tableContainerGap - scrollingContainerTop + tableTopGap;
                top = gap > 0 ? gap : 0;
                triggerFloatEvent(false);
              } else if(scrollingContainerTop - tableContainerGap > tableHeight - floatContainerHeight){
                // scrolled past table but there is space in the container under it..
                top = tableHeight - floatContainerHeight - scrollingContainerTop - tableContainerGap;
              } else {
                top = wrappedContainer ? tableTopGap : scrollingContainerTop;
                //headers stop at the top of the viewport
                triggerFloatEvent(true);
              }
              left = tableLeftGap;
            } else if(!locked && useAbsolutePositioning) { //window scrolling, absolute positioning
              if(windowTop > floatEnd + tableHeight + captionScrollOffset){
                top = tableHeight - floatContainerHeight + captionScrollOffset + scrollingBottom; //scrolled past table
              } else if (tableOffset.top >= windowTop + scrollingTop) {
                top = 0; //scrolling to table
                unfloat();
                triggerFloatEvent(false);
              } else {
                top = scrollingTop + windowTop - tableOffset.top + tableContainerGap + (captionAlignTop ? captionHeight : 0);
                refloat(); //scrolling within table. header floated
                triggerFloatEvent(true);
              }
              left =  scrollContainerLeft;
            } else if(locked && !useAbsolutePositioning){ //inner scrolling, fixed positioning
              if (tableContainerGap > scrollingContainerTop || scrollingContainerTop - tableContainerGap > tableHeight) {
                top = tableOffset.top - windowTop;
                unfloat();
                triggerFloatEvent(false);
              } else {
                top = tableOffset.top + scrollingContainerTop  - windowTop - tableContainerGap;
                refloat();
                triggerFloatEvent(true);
                //headers stop at the top of the viewport
              }
              left = tableOffset.left + scrollContainerLeft - windowLeft;
            } else if(!locked && !useAbsolutePositioning) { //window scrolling, fixed positioning
              if(windowTop > floatEnd + tableHeight + captionScrollOffset){
                top = tableHeight + scrollingTop - windowTop + floatEnd + captionScrollOffset;
                //scrolled past the bottom of the table
              } else if (tableOffset.top > windowTop + scrollingTop) {
                top = tableOffset.top - windowTop;
                refloat();
                triggerFloatEvent(false); //this is a weird case, the header never gets unfloated and i have no no way to know
                //scrolled past the top of the table
              } else {
                //scrolling within the table
                top = scrollingTop;
                triggerFloatEvent(true);
              }
              left = tableOffset.left + scrollContainerLeft - windowLeft;
            }
            return {top: Math.round(top), left: Math.round(left)};
          };
        }