-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathct-scroll-threshold.ts
More file actions
95 lines (88 loc) · 2.8 KB
/
Copy pathct-scroll-threshold.ts
File metadata and controls
95 lines (88 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { LitElement, css, html } from "lit";
import { customElement, property, query } from "lit/decorators.js";
/**
* @element ct-scroll-threshold
*/
@customElement("ct-scroll-threshold")
export class CtScrollThreshold extends LitElement {
static styles = [
css`
:host {
display: block;
}
`
];
@property({ type: Number }) threshold = 0.9;
@property({ type: Object }) scrollTarget = globalThis?.document?.body;
observer?: IntersectionObserver & { POLL_INTERVAL?: number };
@query("#threshold") $threshold!: HTMLDivElement;
render() {
return html`<slot></slot>
<div id="threshold"></div>`;
}
firstUpdated() {
this.#observe();
}
#observe(polyfilled: boolean = false) {
if (window.IntersectionObserver) {
this.observer = new window.IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.observer?.unobserve(this.$threshold);
this.dispatchEvent(new CustomEvent("lower-threshold", { detail: {} }));
}
});
},
{ threshold: this.threshold, root: this.scrollTarget }
);
if (polyfilled) {
// issue 23 - Edge does not reliably dispatch scroll events
// issue 36 - Safari iOS does not reliably get scroll events with iron-scroll-target
// - At this point all pollyfilled browsers need polling :(
this.observer.POLL_INTERVAL = 120;
}
// observe this element
this.observer.observe(this.$threshold);
} else {
let polyfillScript = document.getElementById("polyfill-IntersectionObserver") as HTMLScriptElement;
if (!polyfillScript) {
// load the intersection-observer polyfill script
polyfillScript = document.createElement("script");
polyfillScript.id = "polyfill-IntersectionObserver";
// The current version, 0.3.0, supports Safari which now has
// native shadow DOM. The version currently served by polyfill.io
// does not support native shadow dom.
//
// Until the polyfill is updated to 0.3.0 or greater on polyfill.io
// we will use version 0.3.0 and include it with the element.
//
polyfillScript.src = "https://unpkg.com/intersection-observer@0.12.0/intersection-observer.js";
polyfillScript.async = true;
document.head.appendChild(polyfillScript);
}
// listen for the polyfill to finish loading
// then retry the initLazyLoad process
polyfillScript.addEventListener("load", () => this.#observe(true));
}
}
toggleScrollListener(enable: boolean) {
if (enable) {
this.observer?.observe(this.$threshold);
} else {
this.observer?.unobserve(this.$threshold);
}
}
clearTriggers() {
this.observer?.observe(this.$threshold);
}
disconnectedCallback() {
super.disconnectedCallback();
this.observer?.disconnect();
}
}
declare global {
interface HTMLElementTagNameMap {
"ct-scroll-threshold": CtScrollThreshold;
}
}