vue-use-intersection-observer 1.0.16 → 2.0.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/README.md
CHANGED
|
@@ -16,12 +16,12 @@ Simple and lightweight visibility observer for **vue 3**, built on top of `Inter
|
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- Vue 3 plugin
|
|
20
|
-
- Composable API
|
|
21
|
-
- Uses native `IntersectionObserver`
|
|
22
|
-
- Supports offsets and reactivity
|
|
23
|
-
- One global observer (better performance)
|
|
24
|
-
- Fully written in TypeScript
|
|
19
|
+
- 🧩 Vue 3 plugin
|
|
20
|
+
- 🔌 Composable API
|
|
21
|
+
- 🔍 Uses native `IntersectionObserver`
|
|
22
|
+
- ⚡ Supports offsets and reactivity
|
|
23
|
+
- 🌐 One global observer (better performance)
|
|
24
|
+
- 🛡️ Fully written in TypeScript
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
@@ -49,9 +49,9 @@ app.use(VisibilityPlugin);
|
|
|
49
49
|
app.mount('#app');
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
### Usage (
|
|
52
|
+
### Usage (examples)
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
**# Example with composable**
|
|
55
55
|
|
|
56
56
|
```vue
|
|
57
57
|
<template>
|
|
@@ -65,9 +65,9 @@ In a component
|
|
|
65
65
|
borderRadius: '50%',
|
|
66
66
|
backgroundColor: isvisible ? 'green' : 'red',
|
|
67
67
|
}"
|
|
68
|
-
|
|
68
|
+
></div>
|
|
69
69
|
|
|
70
|
-
<div style="height: 150vh"
|
|
70
|
+
<div style="height: 150vh"></div>
|
|
71
71
|
|
|
72
72
|
<div ref="target" style="width: 200px; height: 200px; background: gray">
|
|
73
73
|
Observed Element
|
|
@@ -98,6 +98,56 @@ onBeforeUnmount(() => {
|
|
|
98
98
|
</script>
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
**# Example with directive**
|
|
104
|
+
|
|
105
|
+
```vue
|
|
106
|
+
<template>
|
|
107
|
+
<div
|
|
108
|
+
:style="{
|
|
109
|
+
position: 'fixed',
|
|
110
|
+
top: '20px',
|
|
111
|
+
right: '20px',
|
|
112
|
+
width: '40px',
|
|
113
|
+
height: '40px',
|
|
114
|
+
borderRadius: '50%',
|
|
115
|
+
backgroundColor: isvisible ? 'green' : 'red',
|
|
116
|
+
}"
|
|
117
|
+
></div>
|
|
118
|
+
|
|
119
|
+
<div style="height: 150vh"></div>
|
|
120
|
+
|
|
121
|
+
<div
|
|
122
|
+
v-visible="onVisible"
|
|
123
|
+
style="width: 200px; height: 200px; background: gray"
|
|
124
|
+
>
|
|
125
|
+
Observed Element
|
|
126
|
+
</div>
|
|
127
|
+
</template>
|
|
128
|
+
|
|
129
|
+
<script setup lang="ts">
|
|
130
|
+
import { ref } from 'vue';
|
|
131
|
+
|
|
132
|
+
const isvisible = ref<boolean>(false);
|
|
133
|
+
|
|
134
|
+
const onVisible = (visible: boolean) => {
|
|
135
|
+
isvisible.value = visible;
|
|
136
|
+
};
|
|
137
|
+
</script>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
> ---
|
|
141
|
+
>
|
|
142
|
+
> The `v-visible` directive is intended for simple use cases.
|
|
143
|
+
> It only accepts a callback function and always reports the visibility state.
|
|
144
|
+
> For advanced configuration (once, offset, threshold), use the composable API.
|
|
145
|
+
> By default always tracks visibility changes (`once` is implicitly set to `false`).
|
|
146
|
+
>
|
|
147
|
+
> ---
|
|
148
|
+
|
|
149
|
+
<p></p>
|
|
150
|
+
|
|
101
151
|
### API
|
|
102
152
|
|
|
103
153
|
#### `useIntersectionObserver()`
|
|
@@ -121,6 +171,8 @@ Start observing an element.
|
|
|
121
171
|
| target | ref | Element ref to observe | true | — |
|
|
122
172
|
| options | Options | Observer configuration | true | — |
|
|
123
173
|
|
|
174
|
+
<p></p>
|
|
175
|
+
|
|
124
176
|
**Options:**
|
|
125
177
|
|
|
126
178
|
| Name | Type | Description | Required | Default |
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { DirectiveBinding } from 'vue';
|
|
2
|
-
import { type
|
|
3
|
-
interface DirectiveValue extends VisibilityOptions {
|
|
4
|
-
callback: VisibilityCallback;
|
|
5
|
-
}
|
|
2
|
+
import { type VisibilityCallback } from '../core/visibilityObserver';
|
|
6
3
|
export declare const vVisible: {
|
|
7
|
-
mounted(el: HTMLElement, binding: DirectiveBinding<
|
|
4
|
+
mounted(el: HTMLElement, binding: DirectiveBinding<VisibilityCallback>): void;
|
|
8
5
|
unmounted(el: HTMLElement): void;
|
|
9
6
|
};
|
|
10
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inject as f, onBeforeUnmount as k } from "vue";
|
|
2
|
-
class
|
|
2
|
+
class l {
|
|
3
3
|
buckets = /* @__PURE__ */ new Map();
|
|
4
4
|
buildRootMargin(e = 0) {
|
|
5
5
|
return `0px 0px -${e}px 0px`;
|
|
@@ -11,15 +11,15 @@ class u {
|
|
|
11
11
|
getBucket(e = 0, s = 0) {
|
|
12
12
|
const t = this.getKey(e, s), r = this.buckets.get(t);
|
|
13
13
|
if (r) return r;
|
|
14
|
-
const
|
|
14
|
+
const i = {
|
|
15
15
|
elements: /* @__PURE__ */ new Map(),
|
|
16
16
|
observer: new IntersectionObserver(
|
|
17
|
-
(
|
|
18
|
-
for (const
|
|
19
|
-
const
|
|
20
|
-
if (!
|
|
21
|
-
const
|
|
22
|
-
|
|
17
|
+
(c) => {
|
|
18
|
+
for (const b of c) {
|
|
19
|
+
const o = i.elements.get(b.target);
|
|
20
|
+
if (!o) continue;
|
|
21
|
+
const u = b.isIntersecting;
|
|
22
|
+
o.lastVisible !== u && (o.lastVisible = u, o.callback(u, b), u && o.once && this.unobserve(b.target));
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
{
|
|
@@ -29,14 +29,15 @@ class u {
|
|
|
29
29
|
}
|
|
30
30
|
)
|
|
31
31
|
};
|
|
32
|
-
return this.buckets.set(t,
|
|
32
|
+
return this.buckets.set(t, i), i;
|
|
33
33
|
}
|
|
34
34
|
observe(e, s, t = {}) {
|
|
35
|
-
const r = t.offset ?? 0,
|
|
36
|
-
|
|
35
|
+
const r = t.offset ?? 0, i = t.threshold ?? 0, c = this.getBucket(r, i);
|
|
36
|
+
c.elements.set(e, {
|
|
37
37
|
callback: s,
|
|
38
|
-
once: t.once ?? !0
|
|
39
|
-
|
|
38
|
+
once: t.once ?? !0,
|
|
39
|
+
lastVisible: void 0
|
|
40
|
+
}), c.observer.observe(e);
|
|
40
41
|
}
|
|
41
42
|
unobserve(e) {
|
|
42
43
|
for (const [s, t] of this.buckets)
|
|
@@ -51,22 +52,22 @@ class u {
|
|
|
51
52
|
this.buckets.clear();
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
const v = new
|
|
55
|
+
const v = new l(), g = {
|
|
55
56
|
mounted(n, e) {
|
|
56
|
-
v.observe(n, e.value
|
|
57
|
+
v.observe(n, e.value, { once: !1 });
|
|
57
58
|
},
|
|
58
59
|
unmounted(n) {
|
|
59
60
|
v.unobserve(n);
|
|
60
61
|
}
|
|
61
|
-
}, a = /* @__PURE__ */ Symbol("VisibilityObserver"),
|
|
62
|
+
}, a = /* @__PURE__ */ Symbol("VisibilityObserver"), y = {
|
|
62
63
|
install(n) {
|
|
63
|
-
const e = new
|
|
64
|
+
const e = new l();
|
|
64
65
|
n.provide(a, e), n.directive("visible", g);
|
|
65
66
|
}
|
|
66
67
|
};
|
|
67
68
|
function h() {
|
|
68
|
-
const n = f(a, null), e = n ?? new
|
|
69
|
-
r.value && e.observe(r.value,
|
|
69
|
+
const n = f(a, null), e = n ?? new l(), s = (r, i) => {
|
|
70
|
+
r.value && e.observe(r.value, i.callback, i);
|
|
70
71
|
}, t = (r) => {
|
|
71
72
|
r.value && e.unobserve(r.value);
|
|
72
73
|
};
|
|
@@ -78,6 +79,6 @@ function h() {
|
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
export {
|
|
81
|
-
|
|
82
|
+
y as VisibilityPlugin,
|
|
82
83
|
h as useIntersectionObserver
|
|
83
84
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(r,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],c):(r=typeof globalThis<"u"?globalThis:r||self,c(r.VueVisibilityObserver={},r.Vue))})(this,(function(r,c){"use strict";class
|
|
1
|
+
(function(r,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],c):(r=typeof globalThis<"u"?globalThis:r||self,c(r.VueVisibilityObserver={},r.Vue))})(this,(function(r,c){"use strict";class f{buckets=new Map;buildRootMargin(e=0){return`0px 0px -${e}px 0px`}getKey(e=0,s=0){const t=Array.isArray(s)?s.join(","):String(s);return`${e}|${t}`}getBucket(e=0,s=0){const t=this.getKey(e,s),i=this.buckets.get(t);if(i)return i;const o={elements:new Map,observer:new IntersectionObserver(b=>{for(const l of b){const u=o.elements.get(l.target);if(!u)continue;const v=l.isIntersecting;u.lastVisible!==v&&(u.lastVisible=v,u.callback(v,l),v&&u.once&&this.unobserve(l.target))}},{root:null,rootMargin:this.buildRootMargin(e),threshold:s})};return this.buckets.set(t,o),o}observe(e,s,t={}){const i=t.offset??0,o=t.threshold??0,b=this.getBucket(i,o);b.elements.set(e,{callback:s,once:t.once??!0,lastVisible:void 0}),b.observer.observe(e)}unobserve(e){for(const[s,t]of this.buckets)if(t.elements.has(e)){t.elements.delete(e),t.observer.unobserve(e),t.elements.size===0&&(t.observer.disconnect(),this.buckets.delete(s));return}}disconnect(){for(const[,e]of this.buckets)e.elements.clear(),e.observer.disconnect();this.buckets.clear()}}const a=new f,y={mounted(n,e){a.observe(n,e.value,{once:!1})},unmounted(n){a.unobserve(n)}},d=Symbol("VisibilityObserver"),g={install(n){const e=new f;n.provide(d,e),n.directive("visible",y)}};function k(){const n=c.inject(d,null),e=n??new f,s=(i,o)=>{i.value&&e.observe(i.value,o.callback,o)},t=i=>{i.value&&e.unobserve(i.value)};return c.onBeforeUnmount(()=>{n||e.disconnect()}),{observe:s,unobserve:t}}r.VisibilityPlugin=g,r.useIntersectionObserver=k,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
|