Files
thetool/public/plugins/vue/tt-core/composables/useIntersectionObserver.js
2025-12-09 05:34:24 +00:00

101 lines
2.8 KiB
JavaScript

/**
* TT-Core Intersection Observer Composable (Vue 3)
* Provides lazy-loading and visibility detection
*/
/**
* Create an intersection observer composable
* @param {Function} callback - Callback when element becomes visible
* @param {Object} options - Observer options
* @returns {Object} - Composable with ref and cleanup
*/
export function useIntersectionObserver(callback, options = {}) {
const { ref, onMounted, onBeforeUnmount } = Vue;
const targetRef = ref(null);
let observer = null;
onMounted(() => {
const threshold = options.threshold || 0.1;
const rootMargin = options.rootMargin || '0px';
const once = options.once !== undefined ? options.once : true;
observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
callback(entry);
if (once && observer) {
observer.disconnect();
observer = null;
}
}
},
{ threshold, rootMargin, root: options.root || null }
);
if (targetRef.value) {
observer.observe(targetRef.value);
}
});
onBeforeUnmount(() => {
if (observer) {
observer.disconnect();
observer = null;
}
});
return {
targetRef
};
}
/**
* Create an intersection observer mixin (backward compatibility)
* @param {Object} options - Observer options
* @returns {Object} - Vue mixin
*/
export function createIntersectionObserverMixin(options = {}) {
return {
data() {
return {
isVisible: false,
hasBeenVisible: false,
observer: null
};
},
mounted() {
this.setupObserver();
},
beforeUnmount() {
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
},
methods: {
setupObserver() {
const threshold = options.threshold || 0.1;
const rootMargin = options.rootMargin || '0px';
this.observer = new IntersectionObserver(
([entry]) => {
this.isVisible = entry.isIntersecting;
if (entry.isIntersecting && !this.hasBeenVisible) {
this.hasBeenVisible = true;
if (this.onFirstVisible) {
this.onFirstVisible();
}
}
},
{ threshold, rootMargin }
);
if (this.$refs.root) {
this.observer.observe(this.$refs.root);
}
}
}
};
}