Created
October 21, 2019 17:28
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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