Skip to content

Instantly share code, notes, and snippets.

@th3hunt
Created March 7, 2016 19:02
Show Gist options
  • Save th3hunt/00975a1ada1f68f706a5 to your computer and use it in GitHub Desktop.
Save th3hunt/00975a1ada1f68f706a5 to your computer and use it in GitHub Desktop.
Stickier Headers - a jQuery plugin prototype
(function($) {
$.fn.stickyHeaders = function({
headerHeight= 60
} = {}) {
const $container = this; // i
const $fakeHeader = $container.find('.fake-header');
$container.on("scroll touchstart touchmove", function() {
const scrollTop = $container.scrollTop();
const offsets = [];
let $previousHeader;
$fakeHeader.toggleClass('hide', scrollTop < 0);
function readHeader(index) {
offsets[index] = this.offsetTop;
}
function moveHeader(index) {
const $header = $(this);
const $headerHook = $header.children().eq(0);
const $headerBody = $header.children().eq(1);
const offsetTop = offsets[index];
const nextOffsetTop = offsets[index + 1];
const isActive = offsetTop <= scrollTop && (!nextOffsetTop || nextOffsetTop > scrollTop);
const isNextToActive = offsetTop > scrollTop && (offsetTop - scrollTop) <= headerHeight;
if (scrollTop < 0) {
$header.removeClass('fixed');
$headerHook.empty();
$previousHeader = null;
return;
}
// $headerBody.text(`active: ${isActive} - next: ${isNextToActive}`);
if (isActive) {
if (!$header.hasClass('active')) {
$header.addClass('active');
$fakeHeader.empty().append($headerBody.clone());
}
} else if (isNextToActive && $previousHeader) {
if (!$header.hasClass('hooked')) {
$headerHook.empty().append($previousHeader.clone());
$header.addClass('hooked').removeClass('active');
}
$header.removeClass("active");
} else {
$header.removeClass("active hooked");
}
$previousHeader = $header;
}
requestAnimationFrame(() => {
console.time('animationFrame');
const $headers = $container.children(".content-header");
$headers.each(readHeader);
$headers.each(moveHeader);
console.timeEnd('animationFrame');
});
});
}
}(jQuery));
.header {
position: relative;
display:table-cell;
height: 10vh;
width: 100vw;
vertical-align:middle;
box-sizing: border-box;
background-color: #333;
text-align: center;
color: #fff;
font-size: 1.6em;
z-index: 2
}
.feedback {
position: fixed;
transform: translateZ(0);
top: 50vh;
left: calc(50vw - 100px);
width: 100px;
text-align: center;
color: red;
z-index: 999;
}
.container {
height: 90vh;
position: relative;
z-index: 1;
}
.scrollable {
overflow-y: scroll;
touch-action: pan-y;
-webkit-overflow-scrolling: touch;
}
.hide {
display: none;
}
.fake-header {
position: fixed;
z-index: 2;
width: 100%;
height: 140px;
margin-top: -80px;
padding-top: 80px;
box-sizing: border-box;
background-color: #999;
}
.content-header {
position: relative;
z-index: 3;
height: 60px;
background-color: #999;
overflow: visible;
box-sizing: border-box;
transform: translateZ(0);
will-change: transform;
&.active {
z-index: 1;
}
.content-header-hook {
position: absolute;
width: 100%;
margin-top: -60px;
display: none;
}
&.hooked {
.content-header-hook {
display: block;
}
}
}
.content-header-body {
padding: 20px 0 20px 5px;
width: 100%;
background-color: #999;
box-sizing: border-box;
font-size: 1.2em;
}
.content {
position: relative;
z-index: 1;
min-height: 200px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment