core/observers/document.observer.ts
core/observers/document.observer.ts is a file in Bane's Lab Site. 45 lines of code and 10 definitions.
import { ACTIVE_CLASS } from "#configuration/constants/element.constants";
import { ANCHOR_PREFIX } from "#configuration/constants/document.constants";
import type { Disposer } from "#types/base.types";
const ROOT_MARGIN = "-20% 0px -60% 0px";
const THRESHOLD = [0, 0.25, 0.5, 0.75, 1];
const markActive = function markActive(links: readonly HTMLAnchorElement[], id: string): void {
for (const link of links) {
link.classList.toggle(ACTIVE_CLASS, link.hash === ANCHOR_PREFIX + id);
}
};
const bestEntry = function bestEntry(ratios: ReadonlyMap<string, number>): string | null {
let best: string | null = null;
let bestRatio = 0;
for (const [id, ratio] of ratios) {
if (ratio > bestRatio) {
bestRatio = ratio;
best = id;
}
}
return best;
};
export const observeSections = function observeSections(
sections: readonly Element[],
links: readonly HTMLAnchorElement[],
): Disposer {
const ratios = new Map<string, number>();
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
ratios.set(entry.target.id, entry.isIntersecting ? entry.intersectionRatio : 0);
}
const active = bestEntry(ratios);
if (active !== null) {
markActive(links, active);
}
},
{ rootMargin: ROOT_MARGIN, threshold: THRESHOLD },
);
for (const section of sections) {
observer.observe(section);
}
return () => {
observer.disconnect();
};
};