From 485f8ae2bddd5352beb4874902b97ae5750bc433 Mon Sep 17 00:00:00 2001 From: MattMo Date: Sun, 5 Feb 2023 19:04:08 -0800 Subject: [PATCH] Cleaned up code and improved documentation. Added new OnSeen event that fires the first time the element is seen and stops firing after that. --- ignite-template.js | 72 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/ignite-template.js b/ignite-template.js index 743376f..d2a3c02 100644 --- a/ignite-template.js +++ b/ignite-template.js @@ -711,16 +711,16 @@ class IgniteTemplate { /** * Adds a special on resize event handler to this template that will * fire anytime the element is resized by using a resize observer. You can call this more than once to attach more than one callback. - * @param {Function|IgniteProperty} callback The callback function to be invoked by the event once it fires. + * @param {Function|IgniteProperty} eventCallback The callback function to be invoked by the event once it fires. * @returns {IgniteTemplate} This ignite template so function calls can be chained. */ - onResize(callback) { + onResize(eventCallback) { IgniteRendering.push(); - if (callback instanceof IgniteProperty) { - this._resizeObserverCallback.push(callback.value); - } else if (callback instanceof Function) { - this._resizeObserverCallback.push(callback); + if (eventCallback instanceof IgniteProperty) { + this._resizeObserverCallback.push(eventCallback.value); + } else if (eventCallback instanceof Function) { + this._resizeObserverCallback.push(eventCallback); } IgniteRendering.pop(); @@ -730,22 +730,54 @@ class IgniteTemplate { /** * Adds a special on intersect event handler to this template that will fire * once the element is in view. You can call this more than once to attach more than one callback. - * @param {Function|IgniteProperty} callback The callback function to be invoked by the event once it fires. + * @param {Function|IgniteProperty} eventCallback The callback function to be invoked by the event once it fires. * @returns {IgniteTemplate} This ignite template so function calls can be chained. */ - onIntersect(callback) { + onIntersect(eventCallback) { IgniteRendering.push(); - if (callback instanceof IgniteProperty) { - this._intersectObserverCallback.push(callback.value); - } else if (callback instanceof Function) { - this._intersectObserverCallback.push(callback); + if (eventCallback instanceof IgniteProperty) { + this._intersectObserverCallback.push(eventCallback.value); + } else if (eventCallback instanceof Function) { + this._intersectObserverCallback.push(eventCallback); } IgniteRendering.pop(); return this; } + /** + * Adds a special event handler for this template that will fire the first time the element is seen and does not repeat. + * @param {Function|IgniteProperty} eventCallback The callback function to be invoked once this element becomes visible. + * @returns {IgniteTemplate} This ignite template so function calls can be chained. + */ + onSeen(eventCallback) { + IgniteRendering.push(); + + var wrapped = () => { + if (eventCallback instanceof IgniteProperty) { + eventCallback.value(); + } else if (eventCallback instanceof Function) { + eventCallback(); + } + + //Set our callback to null so that we stop being called. + if (this._intersectObserverCallback) { + for (var i = 0; i < this._intersectObserverCallback.length; i++) { + if (this._intersectObserverCallback[i] == wrapped) { + this._intersectObserverCallback[i] = null; + break; + } + } + } + }; + + this._intersectObserverCallback.push(wrapped); + + IgniteRendering.pop(); + return this; + } + /** * Adds a CSS property to this template with a value and priority. * @param {String} name The name of the CSS property to set. @@ -1210,8 +1242,13 @@ class IgniteTemplate { //Setup a resize observer if needed if (this._resizeObserverCallback && this._resizeObserverCallback.length > 0) { this._resizeObserver = new ResizeObserver(e => { - this._resizeObserverCallback.forEach(callback => callback(e)); + for (var i = 0; i < this._resizeObserverCallback.length; i++) { + if (this._resizeObserverCallback[i]) { + this._resizeObserverCallback[i](e); + } + } }); + this._resizeObserver.observe(this.element); } @@ -1219,9 +1256,14 @@ class IgniteTemplate { if (this._intersectObserverCallback && this._intersectObserverCallback.length > 0) { this._intersectObserver = new IntersectionObserver(results => { if (results[0].isIntersecting) { - this._intersectObserverCallback.forEach(callback => callback(results[0])); + for (var i = 0; i < this._intersectObserverCallback.length; i++) { + if (this._intersectObserverCallback[i]) { + this._intersectObserverCallback[i](results[0]); + } + } } - }, { root: null, trackVisibility: true, delay: 1000 }); + }, { root: null, threshold: 0.25 }); + this._intersectObserver.observe(this.element); }