Last active
January 16, 2024 09:03
-
-
Save bartwttewaall/19530622761255d65a5bc4d66a33baaa to your computer and use it in GitHub Desktop.
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
export function initNavigation() { | |
const navigation = document.querySelector<HTMLElement>("[data-navigation]"); | |
if (navigation) initSticky(navigation); | |
} | |
function initStickyBehaviour(root: HTMLElement) { | |
// hide the top navigation on scroll | |
const topNav = root.querySelector<HTMLElement>("[data-topnav]"); | |
if (!topNav) { | |
// No topNav? Then always be sticky. | |
root.classList.add("is-sticky"); | |
root.style.top = "0px"; | |
return; | |
} | |
// evaluate if the topnav is visible and if its height needs to be taken into account | |
const evaluate = () => { | |
const isSticky = root.classList.contains("is-sticky"); | |
const isMobile = root.classList.contains("is-mobile"); | |
topNav.style.display = isMobile ? "none" : "flex"; | |
root.style.top = | |
isSticky || !isMobile ? `-${getFullHeight(topNav)}px` : "0px"; | |
}; | |
// observe the intersection of topNav | |
const io = new IntersectionObserver( | |
(payload: IntersectionObserverEntry[]) => { | |
const { isIntersecting } = payload[0]; | |
root.classList.toggle("is-sticky", !isIntersecting); | |
evaluate(); | |
} | |
); | |
io.observe(topNav); | |
// observe the body width | |
const ro = new ResizeObserver((entries: ResizeObserverEntry[]) => { | |
const width = | |
entries[0].borderBoxSize?.[0].inlineSize || document.body.clientWidth; | |
root.classList.toggle("is-mobile", width < 768); | |
evaluate(); | |
}); | |
ro.observe(document.body, { box: "border-box" }); | |
} | |
const heightProperties = [ | |
"height", | |
"margin-top", | |
"margin-bottom", | |
"border-top-width", | |
"border-bottom-width", | |
]; | |
function getFullHeight(el: HTMLElement) { | |
const currentStyle = window.getComputedStyle(el); | |
return heightProperties.reduce( | |
(value, key) => value + parseInt(currentStyle.getPropertyValue(key)), | |
0 | |
); | |
} |
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
[data-navigation] { | |
&.is-sticky { | |
postition: sticky; | |
top: 0; | |
z-index: 9999; | |
} | |
} |
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
<section data-navigation> | |
<nav class="flex flex-row justify-between items-center px-10 py-2 border-b text-sm" data-topnav> | |
<div class="flex gap-x-6"> | |
<a href="mailto:[email protected]" rel="nofollow"><i class="bx bxs-envelope mr-1"></i>[email protected]</a> | |
<a href="tel:0000000000" rel="nofollow"><i class="bx bxs-phone mr-1"></i>000 - 0000 000</a> | |
</div> | |
<div class="flex gap-x-6"> | |
<a href="#">Login</a> | |
<a href="#">Register</a> | |
<a href="#">Contact</a> | |
</div> | |
</nav> | |
<nav class="flex flex-row justify-between items-center px-10 py-3" data-mainnav> | |
<a href="/" class="brand">Logo</a> | |
<ul class="navigation" data-links>...</ul> | |
</nav> | |
</section> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment