diff --git a/package.json b/package.json index 42fc3af..8ac8e4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/helpers", - "version": "2.3.2", + "version": "2.4.0", "description": "", "main": "closest.js", "scripts": { diff --git a/visibility.js b/visibility.js new file mode 100644 index 0000000..95cc2ab --- /dev/null +++ b/visibility.js @@ -0,0 +1,52 @@ +/** +@license +Copyright (c) 2025 trading_peter +This program is available under Apache License Version 2.0 +*/ + +/** + * Orchastrates a intersetion observer to execute code if the element becomes visible or hidden/disconnected. + */ +export const Visibility = function(superClass) { + return class extends superClass { + + constructor() { + super(); + + // Create intersection observer + this._observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + this.visibilityChanged(true); + } else { + this.visibilityChanged(false); + } + }); + }); + } + + /** + * Invoked when the element becomes either visible / connected or hidden / disconnected. + * The callback's logic must be able to handle multiple, successive calls with the same state. + * @param {boolean} visible + */ + visibilityChanged(visible) { + console.warn(this.tagName, 'should override onVisible'); + } + + connectedCallback() { + super.connectedCallback(); + // Start observing this element + this._observer.observe(this); + } + + disconnectedCallback() { + super.disconnectedCallback(); + // Clean up + this._observer.unobserve(this); + this._observer.disconnect(); + + this.visibilityChanged(false); + } + }; +}