Skip to content

Instantly share code, notes, and snippets.

@yutahaga
Last active November 10, 2021 08:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yutahaga/7789bd426b3e0c6f36d95a1e2825dd5f to your computer and use it in GitHub Desktop.
Save yutahaga/7789bd426b3e0c6f36d95a1e2825dd5f to your computer and use it in GitHub Desktop.
Intersection Observer を使った侵入監視クラス。default export でシングルトンに使えるインスタンスを提供。
export type EnterObserverListener = (
entry: IntersectionObserverEntry
) => void | Promise<void>;
export interface EnterObserverEntry {
listener: EnterObserverListener;
once: boolean;
}
export class EnterObserver {
protected observer: IntersectionObserver;
protected entries: Map<Element, EnterObserverEntry>;
constructor(options?: IntersectionObserverInit) {
this.entries = new Map();
this.observer = new IntersectionObserver(this.onEnter.bind(this), options);
}
protected onEnter(
entries: IntersectionObserverEntry[],
observer: IntersectionObserver
) {
entries.forEach(entry => {
const targetEntry = this.entries.get(entry.target);
if (!targetEntry) return;
targetEntry.listener(entry);
if (targetEntry.once) {
this.remove(entry.target);
}
});
}
add(el: Element, listener: EnterObserverListener, once?: boolean) {
if (this.entries.has(el)) return;
this.entries.set(el, {
listener,
once: once || false,
});
this.observer.observe(el);
}
remove(el: Element) {
if (!this.entries.has(el)) return;
this.entries.delete(el);
this.observer.unobserve(el);
}
destroy() {
this.observer.disconnect();
}
}
export default new EnterObserver({
root: null,
rootMargin: '128px',
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment