drab
Version:
Interactivity for You
58 lines (57 loc) • 1.8 kB
JavaScript
import { Content, Lifecycle, Trigger, } from "../base/index.js";
/**
* Uses the
* [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
* to add a `data-intersect` attribute to `content` when the `trigger` is intersecting.
*
* ### Events
*
* `intersect`
*
* Fired when the `trigger` enters the viewport.
*
* `exit`
*
* Fired when the `trigger` exits the viewport.
*
* ### Attributes
*
* `threshold`
*
* Specify a `threshold` between `0` and `1` to determine how much of the
* `trigger` should be visible for the intersection to occur.
*/
export class Intersect extends Lifecycle(Trigger(Content())) {
constructor() {
super();
}
/**
* How much of the `trigger` should be visible for the intersection to occur.
* For example, given a threshold of `.5`, the intersection would occur when
* the `trigger` is 50% visible.
*
* @default 0
*/
get #threshold() {
return Number(this.getAttribute("threshold") ?? 0);
}
mount() {
const observer = new IntersectionObserver((entries) => {
// attribute to add or remove from `content`
const attr = "data-intersect";
for (const entry of entries) {
if (entry.isIntersecting) {
this.content().setAttribute(attr, "");
}
else {
this.content().removeAttribute(attr);
}
this.dispatchEvent(new CustomEvent(entry.isIntersecting ? "intersect" : "exit", {
detail: { entry },
}));
}
}, { threshold: this.#threshold });
for (const trigger of this.triggers())
observer.observe(trigger);
}
}