| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- /**
- * 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();
- /**
- * 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();
- const fireObserverCallback = (entry) => {
- const callback = observerCallbacks.get(entry.target);
- callback && callback(entry);
- };
- const fireAllObserverCallbacks = (entries) => {
- entries.forEach(fireObserverCallback);
- };
- function initIntersectionObserver({ root, ...options }) {
- 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];
- }
- function observeIntersection(element, options, callback) {
- const rootInteresectionObserver = initIntersectionObserver(options);
- observerCallbacks.set(element, callback);
- rootInteresectionObserver.observe(element);
- return () => {
- observerCallbacks.delete(element);
- rootInteresectionObserver.unobserve(element);
- };
- }
- export { observeIntersection };
|