1 | "use strict";
|
2 |
|
3 | const {getRootMargin, getIntersectionRatio} = require("./intersectionCalc");
|
4 | const IntersectionObserverEntry = require("./intersectionObserverEntry");
|
5 |
|
6 | module.exports = function FakeIntersectionObserver(browser) {
|
7 | const observed = [];
|
8 |
|
9 | IntersectionObserver._getObserved = function () {
|
10 | return observed;
|
11 | };
|
12 |
|
13 | const intersectionObserverEntry = IntersectionObserverEntry(browser);
|
14 | intersectionObserverEntry.prototype.intersectionRatio = getIntersectionRatio;
|
15 | browser.window.IntersectionObserverEntry = intersectionObserverEntry;
|
16 |
|
17 | return IntersectionObserver;
|
18 |
|
19 | function IntersectionObserver(viewPortUpdate, options) {
|
20 | const toObserve = [];
|
21 | const rootMargin = getRootMargin(options);
|
22 | browser.window.addEventListener("scroll", onScroll);
|
23 | let previousEntries = [];
|
24 |
|
25 | return {
|
26 | disconnect() {
|
27 | toObserve.length = 0;
|
28 | },
|
29 | observe(element) {
|
30 | toObserve.push(element);
|
31 | observed.push(element);
|
32 | const newEntries = [element].map((el) => intersectionObserverEntry(el, rootMargin));
|
33 | viewPortUpdate(newEntries);
|
34 | previousEntries = previousEntries.concat(newEntries);
|
35 | },
|
36 | unobserve(element) {
|
37 | const idx = toObserve.indexOf(element);
|
38 | if (idx > -1) {
|
39 | toObserve.splice(idx, 1);
|
40 | }
|
41 | }
|
42 | };
|
43 |
|
44 | function onScroll() {
|
45 | const entries = toObserve.map((el) => intersectionObserverEntry(el, rootMargin));
|
46 | const changedEntries = entries.filter(hasChanged);
|
47 |
|
48 | if (changedEntries.length > 0) {
|
49 | viewPortUpdate(changedEntries);
|
50 | }
|
51 |
|
52 | previousEntries = entries;
|
53 | }
|
54 |
|
55 | function hasChanged(entry) {
|
56 | const previous = previousEntries.find((x) => x.target === entry.target);
|
57 | if (!previous) return true;
|
58 | return entry.intersectionRatio !== previous.intersectionRatio;
|
59 | }
|
60 | }
|
61 | };
|