diff --git a/README.md b/README.md index d82aecd..b46007c 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,13 @@ Check the `example-*.html` files for some examples. - `getWidthFrom`: Selector of element referenced to set fixed width of "sticky" element. - `widthFromWrapper`: boolean determining whether width of the "sticky" element should be updated to match the wrapper's width. Wrapper is a placeholder for "sticky" element while it is fixed (out of static elements flow), and it's width depends on the context and CSS rules. - `responsiveWidth`: boolean determining whether widths will be recalculated on window resize (using getWidthfrom). +- `followHorizontalScroll`: Boolean telling to sticked element to follow horizontal scrollbar movement instead of staying fixed ## Methods - `sticky(options)`: Initializer. `options` is optional. - `sticky('update')`: Recalculates the element's position. - + ## Events - `sticky-start`: When the element becomes sticky. diff --git a/jquery.sticky.js b/jquery.sticky.js index 48a9b44..7d9ffdd 100644 --- a/jquery.sticky.js +++ b/jquery.sticky.js @@ -22,7 +22,8 @@ center: false, getWidthFrom: '', widthFromWrapper: true, // works only when .getWidthFrom is empty - responsiveWidth: false + responsiveWidth: false, + followHorizontalScroll: false }, $window = $(window), $document = $(document), @@ -32,7 +33,8 @@ var scrollTop = $window.scrollTop(), documentHeight = $document.height(), dwh = documentHeight - windowHeight, - extra = (scrollTop > dwh) ? dwh - scrollTop : 0; + extra = (scrollTop > dwh) ? dwh - scrollTop : 0, + scrollLeft = $window.scrollLeft(); for (var i = 0; i < sticked.length; i++) { var s = sticked[i], @@ -45,16 +47,19 @@ .css({ 'width': '', 'position': '', - 'top': '' + 'top': '', + 'left': '' }); s.stickyElement.parent().removeClass(s.className); s.stickyElement.trigger('sticky-end', [s]); s.currentTop = null; + s.currentLeft = null; } } else { var newTop = documentHeight - s.stickyElement.outerHeight() - s.topSpacing - s.bottomSpacing - scrollTop - extra; + var newLeft = s.leftPosition - scrollLeft; if (newTop < 0) { newTop = newTop + s.topSpacing; } else { @@ -80,6 +85,9 @@ s.stickyElement.trigger('sticky-start', [s]); s.currentTop = newTop; } + if (s.followHorizontalScroll && newLeft !== s.currentLeft && s.stickyElement.css('position') === 'fixed') { + s.stickyElement.css('left', newLeft); + } } } }, @@ -100,6 +108,13 @@ if ( newWidth != null ) { s.stickyElement.css('width', newWidth); } + + if (s.followHorizontalScroll) { + s.leftPosition = s.stickyWrapper.offset().left; + if (s.stickyElement.css('position') === 'fixed') { + scroller(); + } + } } }, methods = { @@ -132,6 +147,7 @@ o.stickyElement = stickyElement; o.stickyWrapper = stickyWrapper; o.currentTop = null; + o.leftPosition = stickyWrapper.offset().left; sticked.push(o); }); @@ -160,6 +176,7 @@ 'width': '', 'position': '', 'top': '', + 'left': '', 'float': '' }) ;