115 lines
3.8 KiB
JavaScript
115 lines
3.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
Object.defineProperty(exports, "useIntersection", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return useIntersection;
|
|
}
|
|
});
|
|
const _react = require("react");
|
|
const _requestidlecallback = require("./request-idle-callback");
|
|
const hasIntersectionObserver = typeof IntersectionObserver === "function";
|
|
const observers = new Map();
|
|
const idList = [];
|
|
function createObserver(options) {
|
|
const id = {
|
|
root: options.root || null,
|
|
margin: options.rootMargin || ""
|
|
};
|
|
const existing = idList.find((obj)=>obj.root === id.root && obj.margin === id.margin);
|
|
let instance;
|
|
if (existing) {
|
|
instance = observers.get(existing);
|
|
if (instance) {
|
|
return instance;
|
|
}
|
|
}
|
|
const elements = new Map();
|
|
const observer = new IntersectionObserver((entries)=>{
|
|
entries.forEach((entry)=>{
|
|
const callback = elements.get(entry.target);
|
|
const isVisible = entry.isIntersecting || entry.intersectionRatio > 0;
|
|
if (callback && isVisible) {
|
|
callback(isVisible);
|
|
}
|
|
});
|
|
}, options);
|
|
instance = {
|
|
id,
|
|
observer,
|
|
elements
|
|
};
|
|
idList.push(id);
|
|
observers.set(id, instance);
|
|
return instance;
|
|
}
|
|
function observe(element, callback, options) {
|
|
const { id, observer, elements } = createObserver(options);
|
|
elements.set(element, callback);
|
|
observer.observe(element);
|
|
return function unobserve() {
|
|
elements.delete(element);
|
|
observer.unobserve(element);
|
|
// Destroy observer when there's nothing left to watch:
|
|
if (elements.size === 0) {
|
|
observer.disconnect();
|
|
observers.delete(id);
|
|
const index = idList.findIndex((obj)=>obj.root === id.root && obj.margin === id.margin);
|
|
if (index > -1) {
|
|
idList.splice(index, 1);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
function useIntersection(param) {
|
|
let { rootRef, rootMargin, disabled } = param;
|
|
const isDisabled = disabled || !hasIntersectionObserver;
|
|
const [visible, setVisible] = (0, _react.useState)(false);
|
|
const elementRef = (0, _react.useRef)(null);
|
|
const setElement = (0, _react.useCallback)((element)=>{
|
|
elementRef.current = element;
|
|
}, []);
|
|
(0, _react.useEffect)(()=>{
|
|
if (hasIntersectionObserver) {
|
|
if (isDisabled || visible) return;
|
|
const element = elementRef.current;
|
|
if (element && element.tagName) {
|
|
const unobserve = observe(element, (isVisible)=>isVisible && setVisible(isVisible), {
|
|
root: rootRef == null ? void 0 : rootRef.current,
|
|
rootMargin
|
|
});
|
|
return unobserve;
|
|
}
|
|
} else {
|
|
if (!visible) {
|
|
const idleCallback = (0, _requestidlecallback.requestIdleCallback)(()=>setVisible(true));
|
|
return ()=>(0, _requestidlecallback.cancelIdleCallback)(idleCallback);
|
|
}
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [
|
|
isDisabled,
|
|
rootMargin,
|
|
rootRef,
|
|
visible,
|
|
elementRef.current
|
|
]);
|
|
const resetVisible = (0, _react.useCallback)(()=>{
|
|
setVisible(false);
|
|
}, []);
|
|
return [
|
|
setElement,
|
|
visible,
|
|
resetVisible
|
|
];
|
|
}
|
|
|
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
Object.defineProperty(exports.default, '__esModule', { value: true });
|
|
Object.assign(exports.default, exports);
|
|
module.exports = exports.default;
|
|
}
|
|
|
|
//# sourceMappingURL=use-intersection.js.map
|