Skip to content

Instantly share code, notes, and snippets.

@wiseoldman
Last active March 12, 2019 09:43
Show Gist options
  • Save wiseoldman/9fc144b26a280857c2827e8389f040f5 to your computer and use it in GitHub Desktop.
Save wiseoldman/9fc144b26a280857c2827e8389f040f5 to your computer and use it in GitHub Desktop.
[NavigationScrollHandler] Add a class to the navigation when scrolling X pixels using requestAnimationFrame for better performance. The snippet also handles fixed navigations with the WordPress admin-bar #navigation
class NavigationScrollHandler {
constructor({ scrollDistance = 100, onEnter = () => {}, onExit = () => {}, headerElement = false } = {}) {
this.onEnter = onEnter;
this.onExit = onExit;
this.scrollDistance = scrollDistance;
this.headerElement = headerElement;
this.visibleAdminBar = document.querySelector('body.admin-bar');
this.lastKnownScrollY = 0;
this.ticking = false;
this.onScroll();
this.addListeners();
}
addListeners() {
window.addEventListener('scroll', () => this.onScroll(), false);
if (this.headerElement) {
window.addEventListener('resize', () => this.wpAdminBarResize(), false);
}
}
onScroll() {
this.lastKnownScrollY = window.scrollY;
this.requestTick();
}
requestTick() {
if(!this.ticking) {
requestAnimationFrame(this.update.bind(this));
}
this.ticking = true;
}
update() {
let currentScrollY = this.lastKnownScrollY;
this.ticking = false;
this.checkScrollDistance(currentScrollY);
this.wpAdminBar(currentScrollY);
}
checkScrollDistance(scrolledDistance) {
if (this.scrollDistance < 1) {
return false;
}
if (scrolledDistance > this.scrollDistance) {
this.onEnter();
} else if (scrolledDistance < this.scrollDistance) {
this.onExit();
}
}
wpAdminBar(scrolledDistance) {
if (!this.headerElement) {
return false;
}
const ADMIN_BAR_HEIGHT = 46;
if (window.innerWidth < 601 && this.visibleAdminBar) {
let topNumber = ADMIN_BAR_HEIGHT - scrolledDistance;
if (scrolledDistance >= ADMIN_BAR_HEIGHT) {
this.headerElement.style.top = 0;
} else {
this.headerElement.style.top = `${topNumber}px`;
}
}
}
wpAdminBarResize() {
if (window.innerWidth > 600) {
this.headerElement.style.top = '';
} else {
this.wpAdminBar(this.lastKnownScrollY);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment