hiding-header
Advanced tools
Comparing version
export function hidingHeader(container) { | ||
var DEFAULT_CONTENT_SELECTOR = '*'; | ||
var DEFAULT_HEIGHT_PROPERTY_NAME = '--hidingHeader-height'; | ||
var DEFAULT_SCROLL_CAP_PROPERTY_NAME = '--hidingHeader-scrollCap'; | ||
var DEFAULT_TOP_OFFSET_PROPERTY_NAME = '--hidingHeader-topOffset'; | ||
var DEFAULT_BOUNDS_HEIGHT_PROPERTY_NAME = '--hidingHeader-bounds-height'; | ||
var contentSelector = DEFAULT_CONTENT_SELECTOR; | ||
var heightPropertyName = DEFAULT_HEIGHT_PROPERTY_NAME; | ||
var scrollCapPropertyName = DEFAULT_SCROLL_CAP_PROPERTY_NAME; | ||
var topOffsetPropertyName = DEFAULT_TOP_OFFSET_PROPERTY_NAME; | ||
var boundsHeightPropertyName = DEFAULT_BOUNDS_HEIGHT_PROPERTY_NAME; | ||
var lastScrollTopPosition = 0; | ||
var contentHeight = 0; | ||
var lastScrollCap = 0; | ||
var topOffset = 0; | ||
var lastContentHeight = 0; | ||
var paused = false; | ||
var lastBoundsHeight = 0; | ||
var content = container.querySelector(contentSelector); | ||
@@ -29,49 +26,42 @@ if (content === null) { | ||
}; | ||
var getTopOffset = function () { | ||
var getGlobalTopOffset = function () { | ||
return container.offsetTop; | ||
}; | ||
var getContainerOffset = function () { | ||
return container.getBoundingClientRect().top; | ||
var getRelativeTopOffset = function () { | ||
var _a; | ||
return getGlobalTopOffset() - (((_a = container.parentElement) === null || _a === void 0 ? void 0 : _a.offsetTop) || 0); | ||
}; | ||
var onScroll = function () { | ||
var parentHeight = getParentHeight(); | ||
var containerOffset = getContainerOffset(); | ||
// Handle top offset | ||
var currentTopOffset = getTopOffset(); | ||
if (topOffset !== currentTopOffset) { | ||
topOffset = currentTopOffset; | ||
container.style.setProperty(topOffsetPropertyName, currentTopOffset + "px"); | ||
} | ||
var globalTopOffset = getGlobalTopOffset(); | ||
// Handle content height | ||
var currentContentHeight = getContentHeight(); | ||
if (contentHeight !== currentContentHeight) { | ||
contentHeight = currentContentHeight; | ||
container.style.setProperty(heightPropertyName, contentHeight + "px"); | ||
var contentHeight = getContentHeight(); | ||
if (lastContentHeight !== contentHeight) { | ||
lastContentHeight = contentHeight; | ||
container.style.setProperty(heightPropertyName, lastContentHeight + "px"); | ||
} | ||
// Handle scroll cap | ||
// Handle bounds height | ||
var scrollTopPosition = window.scrollY; | ||
var isScrollingDown = scrollTopPosition > lastScrollTopPosition; | ||
if (!paused) { | ||
// @TODO: fix offset variant on direction change | ||
var scrollCap = Math.min(parentHeight - contentHeight, (function () { | ||
var scrollCapBottomPosition = lastScrollTopPosition + | ||
containerOffset + | ||
lastScrollCap + | ||
contentHeight; | ||
var maxBoundsHeight = parentHeight - getRelativeTopOffset(); | ||
var boundsHeight = Math.min(maxBoundsHeight, Math.max(contentHeight, (function () { | ||
if (isScrollingDown) { | ||
var newScrollCap = scrollTopPosition - contentHeight; | ||
return scrollCapBottomPosition < scrollTopPosition | ||
? newScrollCap | ||
: lastScrollCap; | ||
var newBoundsHeight = scrollTopPosition - globalTopOffset; | ||
if (lastBoundsHeight < newBoundsHeight) { | ||
return newBoundsHeight; | ||
} | ||
return lastBoundsHeight; | ||
} | ||
else { | ||
var newScrollCap = scrollTopPosition; | ||
return newScrollCap < scrollCapBottomPosition - contentHeight | ||
? newScrollCap | ||
: lastScrollCap; | ||
var newBoundsHeight = scrollTopPosition - globalTopOffset + contentHeight; | ||
if (lastBoundsHeight > newBoundsHeight) { | ||
return newBoundsHeight; | ||
} | ||
return lastBoundsHeight; | ||
} | ||
})()); | ||
if (scrollCap !== lastScrollCap) { | ||
container.style.setProperty(scrollCapPropertyName, scrollCap + "px"); | ||
lastScrollCap = scrollCap; | ||
})())); | ||
if (boundsHeight !== lastBoundsHeight) { | ||
container.style.setProperty(boundsHeightPropertyName, boundsHeight + "px"); | ||
lastBoundsHeight = boundsHeight; | ||
} | ||
@@ -78,0 +68,0 @@ } |
{ | ||
"name": "hiding-header", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"description": "Toggles header visibility on scroll.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -35,11 +35,8 @@ # Hiding Header [](https://www.npmjs.com/package/hiding-header) [](https://www.npmjs.com/package/hiding-header?activeTab=dependencies)  | ||
position: relative; | ||
--hidingHeader-height: auto; | ||
--hidingHeader-scrollCap: 0px; | ||
--hidingHeader-topOffset: 0px; | ||
--hidingHeader-height: 0px; | ||
--hidingHeader-bounds-height: 0px; | ||
z-index: 10; | ||
height: calc( | ||
var(--hidingHeader-scrollCap) + var(--hidingHeader-height) - var(--hidingHeader-topOffset) | ||
); | ||
height: var(--hidingHeader-bounds-height); | ||
margin-bottom: calc( | ||
var(--hidingHeader-topOffset) - var(--hidingHeader-scrollCap) | ||
var(--hidingHeader-height) - var(--hidingHeader-bounds-height) | ||
); | ||
@@ -46,0 +43,0 @@ pointer-events: none; |
export function hidingHeader(container: HTMLElement) { | ||
const DEFAULT_CONTENT_SELECTOR = '*' | ||
const DEFAULT_HEIGHT_PROPERTY_NAME = '--hidingHeader-height' | ||
const DEFAULT_SCROLL_CAP_PROPERTY_NAME = '--hidingHeader-scrollCap' | ||
const DEFAULT_TOP_OFFSET_PROPERTY_NAME = '--hidingHeader-topOffset' | ||
const DEFAULT_BOUNDS_HEIGHT_PROPERTY_NAME = '--hidingHeader-bounds-height' | ||
const contentSelector = DEFAULT_CONTENT_SELECTOR | ||
const heightPropertyName = DEFAULT_HEIGHT_PROPERTY_NAME | ||
const scrollCapPropertyName = DEFAULT_SCROLL_CAP_PROPERTY_NAME | ||
const topOffsetPropertyName = DEFAULT_TOP_OFFSET_PROPERTY_NAME | ||
const boundsHeightPropertyName = DEFAULT_BOUNDS_HEIGHT_PROPERTY_NAME | ||
let lastScrollTopPosition = 0 | ||
let contentHeight = 0 | ||
let lastScrollCap = 0 | ||
let topOffset = 0 | ||
let lastContentHeight = 0 | ||
let paused = false | ||
let lastBoundsHeight = 0 | ||
@@ -36,8 +33,8 @@ const content = container.querySelector(contentSelector) | ||
const getTopOffset = () => { | ||
const getGlobalTopOffset = () => { | ||
return container.offsetTop | ||
} | ||
const getContainerOffset = () => { | ||
return container.getBoundingClientRect().top | ||
const getRelativeTopOffset = () => { | ||
return getGlobalTopOffset() - (container.parentElement?.offsetTop || 0) | ||
} | ||
@@ -47,22 +44,12 @@ | ||
const parentHeight = getParentHeight() | ||
const containerOffset = getContainerOffset() | ||
const globalTopOffset = getGlobalTopOffset() | ||
// Handle top offset | ||
const currentTopOffset = getTopOffset() | ||
if (topOffset !== currentTopOffset) { | ||
topOffset = currentTopOffset | ||
container.style.setProperty( | ||
topOffsetPropertyName, | ||
`${currentTopOffset}px` | ||
) | ||
} | ||
// Handle content height | ||
const currentContentHeight = getContentHeight() | ||
if (contentHeight !== currentContentHeight) { | ||
contentHeight = currentContentHeight | ||
container.style.setProperty(heightPropertyName, `${contentHeight}px`) | ||
const contentHeight = getContentHeight() | ||
if (lastContentHeight !== contentHeight) { | ||
lastContentHeight = contentHeight | ||
container.style.setProperty(heightPropertyName, `${lastContentHeight}px`) | ||
} | ||
// Handle scroll cap | ||
// Handle bounds height | ||
const scrollTopPosition = window.scrollY | ||
@@ -72,27 +59,33 @@ const isScrollingDown = scrollTopPosition > lastScrollTopPosition | ||
if (!paused) { | ||
// @TODO: fix offset variant on direction change | ||
const scrollCap = Math.min( | ||
parentHeight - contentHeight, | ||
(() => { | ||
const scrollCapBottomPosition = | ||
lastScrollTopPosition + | ||
containerOffset + | ||
lastScrollCap + | ||
contentHeight | ||
if (isScrollingDown) { | ||
const newScrollCap = scrollTopPosition - contentHeight | ||
return scrollCapBottomPosition < scrollTopPosition | ||
? newScrollCap | ||
: lastScrollCap | ||
} else { | ||
const newScrollCap = scrollTopPosition | ||
return newScrollCap < scrollCapBottomPosition - contentHeight | ||
? newScrollCap | ||
: lastScrollCap | ||
} | ||
})() | ||
const maxBoundsHeight = parentHeight - getRelativeTopOffset() | ||
const boundsHeight = Math.min( | ||
maxBoundsHeight, | ||
Math.max( | ||
contentHeight, | ||
(() => { | ||
if (isScrollingDown) { | ||
const newBoundsHeight = scrollTopPosition - globalTopOffset | ||
if (lastBoundsHeight < newBoundsHeight) { | ||
return newBoundsHeight | ||
} | ||
return lastBoundsHeight | ||
} else { | ||
const newBoundsHeight = | ||
scrollTopPosition - globalTopOffset + contentHeight | ||
if (lastBoundsHeight > newBoundsHeight) { | ||
return newBoundsHeight | ||
} | ||
return lastBoundsHeight | ||
} | ||
})() | ||
) | ||
) | ||
if (scrollCap !== lastScrollCap) { | ||
container.style.setProperty(scrollCapPropertyName, `${scrollCap}px`) | ||
lastScrollCap = scrollCap | ||
if (boundsHeight !== lastBoundsHeight) { | ||
container.style.setProperty( | ||
boundsHeightPropertyName, | ||
`${boundsHeight}px` | ||
) | ||
lastBoundsHeight = boundsHeight | ||
} | ||
@@ -99,0 +92,0 @@ } |
Sorry, the diff of this file is not supported yet
11529
-7.07%207
-8%64
-4.48%