@opensig/opendesign
Version:
91 lines (90 loc) • 2.52 kB
JavaScript
import { isFunction } from "../_utils/is.mjs";
const defaultKey = {};
const instancePool = /* @__PURE__ */ new WeakMap();
function createObserverInstance(options) {
let instance = instancePool.get(options || defaultKey);
if (!instance) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
var _a;
const ele = entry.target;
const ins = instance == null ? void 0 : instance.elementPool.get(ele);
if (!ins) {
return;
}
(_a = ins == null ? void 0 : ins.callbacks) == null ? void 0 : _a.forEach((fn) => fn(entry, entry.isIntersecting));
});
}, options);
const elementPool = /* @__PURE__ */ new WeakMap();
instance = {
observer,
record: 0,
elementPool
};
instancePool.set(options || defaultKey, instance);
}
return instance;
}
function useIntersectionObserver(options) {
const instance = createObserverInstance(options);
return {
/**
* 监听实例
*/
observer: instance.observer,
/**
* 创建监听实例
* el: 添加监听的元素
* listener: 进入视口回调, 移除监听时需要指定该监听函数
*/
observe: (el, listener) => {
if (!el || !isFunction(listener)) {
return null;
}
const val = instance.elementPool.get(el);
if (val) {
val.callbacks.push(listener);
} else {
instance.observer.observe(el);
instance.record++;
instance.elementPool.set(el, {
element: el,
callbacks: [listener]
});
}
return instance.observer;
},
/**
* 移除对某元素的监听
* el: 要移除监听的元素
* listener: 要移除的监听函数,如果不传,则使用初始化时的回调
*/
unobserve: (el, listener) => {
if (!el || !isFunction(listener) || !instance) {
return;
}
const val = instance.elementPool.get(el);
if (val) {
const idx = val.callbacks.indexOf(listener);
val.callbacks.splice(idx, 1);
if (val.callbacks.length === 0) {
instance.observer.unobserve(el);
instance.elementPool.delete(el);
instance.record--;
if (instance.record === 0) {
instance.observer.disconnect();
}
}
}
},
/**
* 销毁观察器
*/
destroy() {
instance.observer.disconnect();
}
};
}
export {
useIntersectionObserver
};