svelte-intersection-observer 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IntersectionObserver.svelte +5 -1
- package/MultipleIntersectionObserver.svelte +7 -1
- package/README.md +42 -2
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/intersect.svelte.d.ts +18 -0
- package/intersect.svelte.js +12 -0
- package/package.json +1 -1
|
@@ -48,7 +48,11 @@
|
|
|
48
48
|
onobserve?.(_entry);
|
|
49
49
|
|
|
50
50
|
if (_entry.isIntersecting) {
|
|
51
|
-
onintersect?.(
|
|
51
|
+
onintersect?.(
|
|
52
|
+
/** @type {IntersectionObserverEntry & { isIntersecting: true }} */ (
|
|
53
|
+
_entry
|
|
54
|
+
),
|
|
55
|
+
);
|
|
52
56
|
|
|
53
57
|
if (element && once) observer?.unobserve(element);
|
|
54
58
|
}
|
|
@@ -50,7 +50,13 @@
|
|
|
50
50
|
onobserve?.({ entry: _entry, target });
|
|
51
51
|
|
|
52
52
|
if (_entry.isIntersecting) {
|
|
53
|
-
onintersect?.({
|
|
53
|
+
onintersect?.({
|
|
54
|
+
entry:
|
|
55
|
+
/** @type {IntersectionObserverEntry & { isIntersecting: true }} */ (
|
|
56
|
+
_entry
|
|
57
|
+
),
|
|
58
|
+
target,
|
|
59
|
+
});
|
|
54
60
|
if (once) observer?.unobserve(target);
|
|
55
61
|
}
|
|
56
62
|
}
|
package/README.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
# svelte-intersection-observer
|
|
2
2
|
|
|
3
|
+
<!-- HIDE_START -->
|
|
3
4
|
[![NPM][npm]][npm-url]
|
|
5
|
+
<!-- HIDE_END -->
|
|
4
6
|
|
|
5
7
|
> Detect if an element is in the viewport using the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
|
|
6
8
|
|
|
7
9
|
Use it to lazy-load images, trigger scroll animations, implement infinite scroll, autoplay video when visible, track ad or analytics impressions, or detect when a user has scrolled to the end of a list.
|
|
8
10
|
|
|
9
|
-
This
|
|
11
|
+
This zero-dependency library offers several ways to observe elements:
|
|
12
|
+
|
|
13
|
+
- `IntersectionObserver`: component for observing a single element
|
|
14
|
+
- `MultipleIntersectionObserver`: component for observing multiple elements (shared observer for better performance)
|
|
15
|
+
- `intersect`: action for observing an element directly with `use:`
|
|
16
|
+
- `intersectAttachment`: attachment for observing an element directly with `{@attach}` (Svelte 5.29+)
|
|
10
17
|
|
|
11
18
|
Try it in the [Svelte REPL](https://svelte.dev/repl/8cd2327a580c4f429c71f7df999bd51d).
|
|
12
19
|
|
|
@@ -263,6 +270,37 @@ As an alternative to the `IntersectionObserver` component, use the `intersect` a
|
|
|
263
270
|
|
|
264
271
|
Options passed to `use:intersect` are reactive: updating `root`, `rootMargin`, or `threshold` re-initializes the underlying observer. Updating `skip` toggles observing on the existing observer without re-initializing it.
|
|
265
272
|
|
|
273
|
+
### `intersectAttachment` attachment
|
|
274
|
+
|
|
275
|
+
As of Svelte 5.29, [attachments](https://svelte.dev/docs/svelte/svelte-attachments) are the preferred replacement for actions. `intersectAttachment` wraps the `intersect` action with `svelte/attachments`'s `fromAction`, reusing the same observer logic but plugging into `{@attach ...}` instead of `use:`.
|
|
276
|
+
|
|
277
|
+
Attachments have a few architectural advantages over actions:
|
|
278
|
+
|
|
279
|
+
- No separate `update()` lifecycle method; they rerun reactively like a `$effect`
|
|
280
|
+
- Just plain functions, so they're easier to compose and generate dynamically
|
|
281
|
+
- Can be forwarded through components as ordinary props, unlike actions
|
|
282
|
+
|
|
283
|
+
```svelte
|
|
284
|
+
<script>
|
|
285
|
+
import { intersectAttachment } from "svelte-intersection-observer";
|
|
286
|
+
|
|
287
|
+
let attachmentIntersecting = $state(false);
|
|
288
|
+
</script>
|
|
289
|
+
|
|
290
|
+
<header class:intersecting={attachmentIntersecting}>
|
|
291
|
+
{attachmentIntersecting ? "Element is in view" : "Element is not in view"}
|
|
292
|
+
</header>
|
|
293
|
+
|
|
294
|
+
<div
|
|
295
|
+
{@attach intersectAttachment(() => ({ once: true }))}
|
|
296
|
+
onobserve={(e) => (attachmentIntersecting = e.detail.isIntersecting)}
|
|
297
|
+
>
|
|
298
|
+
Hello world
|
|
299
|
+
</div>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Note**: unlike `use:intersect`, which takes the options object directly, `intersectAttachment` takes a function that _returns_ the options object (this is how `fromAction` tracks reactive dependencies). `intersect` remains fully supported; use whichever fits your codebase.
|
|
303
|
+
|
|
266
304
|
### Multiple elements
|
|
267
305
|
|
|
268
306
|
For performance, use `MultipleIntersectionObserver` to observe multiple elements with a single shared observer instead of instantiating a new one for every element.
|
|
@@ -417,7 +455,9 @@ Both callbacks are called with:
|
|
|
417
455
|
| elementIntersections | `Map<HTMLElement \| null, boolean>` |
|
|
418
456
|
| elementEntries | `Map<HTMLElement \| null,` [`IntersectionObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry)`>` |
|
|
419
457
|
|
|
420
|
-
### `intersect` action
|
|
458
|
+
### `intersect` action / `intersectAttachment` attachment
|
|
459
|
+
|
|
460
|
+
`intersectAttachment` is a thin wrapper around the `intersect` action (see [above](#intersectattachment-attachment)), so both share the same options and dispatched events.
|
|
421
461
|
|
|
422
462
|
#### Options
|
|
423
463
|
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default } from "./IntersectionObserver.svelte";
|
|
2
2
|
export type { IntersectActionOptions } from "./intersect.svelte.js";
|
|
3
|
-
export { intersect } from "./intersect.svelte.js";
|
|
3
|
+
export { intersect, intersectAttachment } from "./intersect.svelte.js";
|
|
4
4
|
export { default as MultipleIntersectionObserver } from "./MultipleIntersectionObserver.svelte";
|
package/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default } from "./IntersectionObserver.svelte";
|
|
2
|
-
export { intersect } from "./intersect.svelte.js";
|
|
2
|
+
export { intersect, intersectAttachment } from "./intersect.svelte.js";
|
|
3
3
|
export { default as MultipleIntersectionObserver } from "./MultipleIntersectionObserver.svelte";
|
package/intersect.svelte.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Action } from "svelte/action";
|
|
2
|
+
import type { Attachment } from "svelte/attachments";
|
|
2
3
|
|
|
3
4
|
export interface IntersectActionOptions {
|
|
4
5
|
/**
|
|
@@ -51,3 +52,20 @@ export const intersect: Action<
|
|
|
51
52
|
) => void;
|
|
52
53
|
}
|
|
53
54
|
>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Svelte attachment that observes the element with the Intersection Observer
|
|
58
|
+
* API. Equivalent to `intersect`, for use with `{@attach}` instead of `use:`.
|
|
59
|
+
*/
|
|
60
|
+
export function intersectAttachment(
|
|
61
|
+
getOptions?: () => IntersectActionOptions,
|
|
62
|
+
): Attachment<HTMLElement>;
|
|
63
|
+
|
|
64
|
+
declare module "svelte/elements" {
|
|
65
|
+
export interface HTMLAttributes<T> {
|
|
66
|
+
onobserve?: (event: CustomEvent<IntersectionObserverEntry>) => void;
|
|
67
|
+
onintersect?: (
|
|
68
|
+
event: CustomEvent<IntersectionObserverEntry & { isIntersecting: true }>,
|
|
69
|
+
) => void;
|
|
70
|
+
}
|
|
71
|
+
}
|
package/intersect.svelte.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { fromAction } from "svelte/attachments";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Svelte action that observes `node` with the Intersection Observer API.
|
|
3
5
|
* Dispatches `observe` (on every change) and `intersect` (on entering the
|
|
@@ -67,3 +69,13 @@ export function intersect(node, options = {}) {
|
|
|
67
69
|
},
|
|
68
70
|
};
|
|
69
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Svelte attachment that observes the element with the Intersection Observer
|
|
75
|
+
* API. Equivalent to the `intersect` action, for use with `{@attach}` instead
|
|
76
|
+
* of `use:`. Wraps `intersect` via `svelte/attachments`'s `fromAction`.
|
|
77
|
+
* @param {() => import("./intersect.svelte.d.ts").IntersectActionOptions} [getOptions]
|
|
78
|
+
*/
|
|
79
|
+
export function intersectAttachment(getOptions = () => ({})) {
|
|
80
|
+
return fromAction(intersect, getOptions);
|
|
81
|
+
}
|
package/package.json
CHANGED