Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 33x 33x 33x 33x 33x | type IntersectionHandler = (entry: IntersectionObserverEntry) => void interface ElementIntersectionObservers { [key: string]: IntersectionObserver } /** * Map an IntersectionHandler callback to an element. We only ever make one handler for one * element, so even though these handlers might all be triggered by different * observers, we can keep them in the same map. */ const observerCallbacks = new WeakMap<Element, IntersectionHandler>() /** * Multiple observers can be created for multiple element/document roots. Each with * different settings. So here we store dictionaries of observers to each root, * using serialised settings (threshold/margin) as lookup keys. */ const observers = new WeakMap< Element | Document, ElementIntersectionObservers >() const fireObserverCallback = (entry: IntersectionObserverEntry) => { observerCallbacks.get(entry.target)?.(entry) } const fireAllObserverCallbacks: IntersectionObserverCallback = (entries) => { entries.forEach(fireObserverCallback) } function initIntersectionObserver({ root, ...options }: IntersectionObserverInit): IntersectionObserver { const lookupRoot = root || document /** * If we don't have an observer lookup map for this root, create one. */ if (!observers.has(lookupRoot)) { observers.set(lookupRoot, {}) } const rootObservers = observers.get(lookupRoot)! const key = JSON.stringify(options) /** * If we don't have an observer for this combination of root and settings, * create one. */ if (!rootObservers[key]) { rootObservers[key] = new IntersectionObserver( fireAllObserverCallbacks, { root, ...options } ) } return rootObservers[key] } export function observeIntersection( element: Element, options: IntersectionObserverInit, callback: IntersectionHandler ) { const rootInteresectionObserver = initIntersectionObserver(options) observerCallbacks.set(element, callback) rootInteresectionObserver.observe(element) return () => { observerCallbacks.delete(element) rootInteresectionObserver.unobserve(element) } } |