|
1 | | -// Registers a scroll event listener on the document that checks if the given |
2 | | -// element is in view and calls the provided handler if it is. |
3 | | -function registerScrollHander(el: HTMLElement, handler: () => void) { |
4 | | - const throttledHandler = throttle(() => lazyLoader(el, handler), 500) |
5 | | - document.addEventListener('scroll', () => throttledHandler()) |
6 | | -} |
| 1 | +class LazyLoader { |
| 2 | + private el: HTMLElement |
| 3 | + private handler: () => void |
| 4 | + private intersectionObserver!: IntersectionObserver |
| 5 | + |
| 6 | + constructor(el: HTMLElement, handler: () => void) { |
| 7 | + this.el = el |
| 8 | + this.handler = handler |
| 9 | + } |
| 10 | + |
| 11 | + public observe() { |
| 12 | + const { el, handler } = this |
| 13 | + |
| 14 | + const cb = (entries: IntersectionObserverEntry[]) => { |
| 15 | + const entry = entries[0] |
| 16 | + if (entry.intersectionRatio > 0) handler() |
| 17 | + } |
7 | 18 |
|
8 | | -// Removes the scroll event listener on the document that was previously added |
9 | | -// with registerScrollHandler. |
10 | | -function canelScrollHander(el: HTMLElement, handler: () => void) { |
11 | | - document.removeEventListener('scroll', () => lazyLoader(el, handler)) |
| 19 | + this.intersectionObserver = new IntersectionObserver(cb) |
| 20 | + this.intersectionObserver.observe(el) |
| 21 | + } |
| 22 | + |
| 23 | + public unobserve() { |
| 24 | + this.intersectionObserver.unobserve(this.el) |
| 25 | + } |
12 | 26 | } |
13 | 27 |
|
14 | | -// Checks if the given element is in view, and if it is, calls the provided handler. |
15 | | -function lazyLoader(el: HTMLElement, handler: () => void): void { |
16 | | - const windowHeight: number = window.innerHeight |
17 | | - const windowOffY: number = window.scrollY |
18 | | - const elDistanceToTop: number = |
19 | | - window.pageYOffset + el.getBoundingClientRect().top |
20 | | - |
21 | | - if ( |
22 | | - elDistanceToTop >= windowOffY - windowHeight / 4 && |
23 | | - elDistanceToTop - windowOffY - windowHeight < windowHeight / 4 |
24 | | - ) |
25 | | - handler() |
| 28 | +let lz: LazyLoader |
| 29 | + |
| 30 | +function lazyLoader(el: HTMLElement, handler: () => void) { |
| 31 | + lz = new LazyLoader(el, handler) |
| 32 | + lz.observe() |
26 | 33 | } |
27 | 34 |
|
28 | | -// Throttle function that delays the execution of the given function until a certain time has passed since the last time it was called. |
29 | | -function throttle(func: () => void, delay: number): () => void { |
30 | | - let timeout: NodeJS.Timeout | undefined |
31 | | - return () => { |
32 | | - if (!timeout) |
33 | | - timeout = setTimeout(() => { |
34 | | - func() |
35 | | - timeout = undefined |
36 | | - }, delay) |
37 | | - } |
| 35 | +function unobserve() { |
| 36 | + lz.unobserve() |
38 | 37 | } |
39 | 38 |
|
40 | | -export { registerScrollHander, canelScrollHander, lazyLoader } |
| 39 | +export { lazyLoader, unobserve } |
0 commit comments