Skip to content

Instantly share code, notes, and snippets.

@natebeaty
Created October 21, 2019 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natebeaty/c5a11e31e714ac17a957386d4cbc4114 to your computer and use it in GitHub Desktop.
Save natebeaty/c5a11e31e714ac17a957386d4cbc4114 to your computer and use it in GitHub Desktop.
es6 module for push-as-you-scroll sticky headers (currently set for vertical, rotated 90º headers)
// Vertical sticky headers with push effect
//
// Use:
// import stickyHeaders from './stickyHeaders';
// stickyHeaders.init($('.sticky-header'), $(window), 20);
//
// Markup:
// <div class="sticky-header">
// <div class="sticky-title">Test Header</div>
// </div>
//
// SCSS
// .sticky-header {
// position: relative;
// .sticky-title {
// transform: rotate(90deg);
// transform-origin: left top;
// position: absolute;
// top: 0;
// left: calc(100% - 20px);
// white-space: nowrap;
// }
// }
export let $stickies = [],
$stickyTitles = [],
offset,
scrollTop,
ticking;
const stickyHeaders = {
// Init sticky headers
init(stickies, target, setOffset) {
offset = setOffset || 0;
if (typeof stickies === 'object' && stickies instanceof $ && stickies.length > 0) {
$stickies = stickies;
stickyHeaders.setStickyPositions();
target.off('scroll.stickies').on('scroll.stickies', stickyHeaders.scrolling);
target.off('resize.stickies').on('resize.stickies', stickyHeaders.resizing);
target.off('load.stickies').on('load.stickies', stickyHeaders.resizing);
}
},
// Request update using requestAnimationFrame
requestTick() {
if(!ticking) {
requestAnimationFrame(stickyHeaders.update);
}
ticking = true;
},
// Update positions of sticky headers
update() {
ticking = false;
$stickies.each(function(i) {
let $this = $(this),
stickyPosition = $this.data('originalPosition'),
newPosition,
$nextSticky;
if (stickyPosition <= scrollTop) {
newPosition = Math.max(offset, scrollTop - stickyPosition);
$nextSticky = $stickies.eq(i + 1);
if($nextSticky.length > 0) {
newPosition = Math.min(newPosition, ($nextSticky.data('originalPosition') - stickyPosition) - $this.data('originalHeight'));
}
} else {
newPosition = offset;
}
$stickyTitles[i].css('top', newPosition + 'px');
});
},
// Recalculate positions/sizes
setStickyPositions() {
$stickies.each(function(i) {
let $this = $(this);
// Cache title elements
$stickyTitles[i] = $this.find('.sticky-title');
$this
.data('originalPosition', $this.offset().top)
.data('originalHeight', $this.find('.sticky-title').outerWidth() + 10);
});
},
// Resizing
resizing(event) {
stickyHeaders.setStickyPositions();
},
// Scrolling
scrolling(event) {
scrollTop = $(event.currentTarget).scrollTop() + 70;
stickyHeaders.requestTick();
}
};
export default stickyHeaders
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment