diff --git a/README.md b/README.md index 0680628..3ea984f 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,18 @@ Some additional attributes are available to allow both of those cases, overridin Some methods are available, to turn on/off Cartapus programmatically : +### `.add(el)` + +Cartapus watches DOM changes and observes automatically appended elements. But in some cases you may need to start observing an element manually (when a `data-cartapus` attribute has been added after the element being appended,etc). + +This method returns `true` if the element is now being watched, `false` if not. + +### `.triggerEvents(targets)` + +Triggers instantly the cartapus events related to the given elements (can be an array of elements, or a single element). + +If `targets` parameter is not given, it triggers the events of **all** observed elements. + ### `.destroy()` Stops observing **all** `[data-cartapus]` elements. And disconnects all the `IntersectionObservers` along with the `MutationObserver`. diff --git a/bundled/cartapus.js b/bundled/cartapus.js index 77e237a..067d216 100644 --- a/bundled/cartapus.js +++ b/bundled/cartapus.js @@ -1 +1 @@ -function e(t,r){return e=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e(t,r)}function t(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(){}a.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function a(){s.off(e,a),t.apply(r,arguments)}return a._=t,this.on(e,a,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,a=r.length;se.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(){}a.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function a(){s.off(e,a),t.apply(r,arguments)}return a._=t,this.on(e,a,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,a=r.length;se.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(){}o.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function o(){s.off(e,o),t.apply(r,arguments)}return o._=t,this.on(e,o,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,o=r.length;se.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(){}o.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function o(){s.off(e,o),t.apply(r,arguments)}return o._=t,this.on(e,o,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,o=r.length;s\n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n findObserverForElement(el) {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","_Emitter","options","_this","intersect","bind","_assertThisInitialized","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","Cartapus","Emitter","elems","document","querySelectorAll","storeNewElement","_step","value","_proto","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","done","entry","isIntersecting","target","setAttribute","unobserve","dispatch","visible","intersection","event","CustomEvent","detail","dispatchEvent","records","_step3","_iterator3","record","type","_step4","_iterator4","_createForOfIteratorHelperLoose","addedNodes","addedNode","_step6","inners","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","_iterator7","_el","_index","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","_step11","_iterator11","destroy","disconnect","_step12","_iterator12","_step13","_iterator13"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cartapus.js","sources":["../node_modules/tiny-emitter/index.js","../src/cartapus.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","/**\n * @file Cartapus core file, dispatches events based on [data-cartapus] elements' visibility in the viewport.\n * @author Jordan Thiervoz \n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n /**\n * Gets the observer configuration object for the given element.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {(undefined|Object)} The found observer object, `undefined` if not found.\n */\n findObserverForElement(el) {\n if (!el) return\n\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n /**\n * Stores a new DOM element to be watched. Creating a new `IntersectionObserver` if needed.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {Boolean} True if a new element is being watched, else false.\n */\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n /**\n * Creates a new `IntersectionObserver` with the given options. Optionally watching a given element.\n *\n * @param {(undefined|Object)} param An object containing parameters.\n * @param {(undefined|Object)} param.options An object containing the `IntersectionObserver` parameters.\n * @param {(undefined|Element)} param.element A DOM Element to start observing with the newly created observer.\n *\n * @returns {Object} An object with the related observer values.\n */\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n /**\n * This method is called on every mutation of the DOM.\n *\n * @param {Array} records A array of MutationRecords.\n *\n * @private\n * @returns {void}\n */\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Triggers the cartapus events for the given targets. If no targets are given, all the elements will trigger their events.\n *\n * @param {(undefined|Array|Element)} targets - An element or an array of elements.\n *\n * @public\n * @returns {void}\n */\n triggerEvent(targets) {\n if (targets) {\n const els = Array.isArray(targets) ? targets : [targets]\n\n for (const el of els) {\n if (el._cartapus) {\n el._cartapus.observer.unobserve(el)\n el._cartapus.observer.observe(el)\n }\n }\n\n return\n }\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Start watching a given Element. Use in case the `data-cartapus` attribute has been added after the Element has been appended to the DOM.\n *\n * @param {Element} el A DOM element to start observing.\n *\n * @returns {Boolean} Whether the Element is now being observed or not.\n */\n add(el) {\n const success = this.storeNewElement(el)\n\n if (success) el._cartapus.observer.observe(el)\n\n return success\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","_Emitter","Cartapus","options","_this","intersect","bind","_assertThisInitialized","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","Emitter","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","_proto","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","CustomEvent","dispatchEvent","event","records","_step3","_iterator3","record","type","addedNodes","addedNode","_step4","_step6","inners","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","_iterator7","_createForOfIteratorHelperLoose","_el","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","triggerEvent","targets","els","Array","isArray","_step12","_step13","_iterator13","_step14","_iterator14","add","success","destroy","disconnect","_step15","_iterator15","_step16"],"mappings":"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"} \ No newline at end of file diff --git a/dist/cartapus.mjs b/dist/cartapus.mjs index 9c73496..ba06747 100644 --- a/dist/cartapus.mjs +++ b/dist/cartapus.mjs @@ -1,2 +1,2 @@ -function e(t,r){return e=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},e(t,r)}function t(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(){}a.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function a(){s.off(e,a),t.apply(r,arguments)}return a._=t,this.on(e,a,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,a=r.length;se.length)&&(t=e.length);for(var r=0,s=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(){}a.prototype={on:function(e,t,r){var s=this.e||(this.e={});return(s[e]||(s[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var s=this;function a(){s.off(e,a),t.apply(r,arguments)}return a._=t,this.on(e,a,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),s=0,a=r.length;s\n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n findObserverForElement(el) {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","Cartapus","_Emitter","options","_this","intersect","bind","_assertThisInitialized","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","Emitter","elems","document","querySelectorAll","storeNewElement","_step","value","_proto","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","done","entry","isIntersecting","target","setAttribute","unobserve","dispatch","visible","intersection","event","CustomEvent","detail","dispatchEvent","records","_step3","_iterator3","record","type","_step4","_iterator4","_createForOfIteratorHelperLoose","addedNodes","addedNode","_step6","inners","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","_iterator7","_el","_index","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","_step11","_iterator11","destroy","disconnect","_step12","_iterator12","_step13","_iterator13"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cartapus.mjs","sources":["../node_modules/tiny-emitter/index.js","../src/cartapus.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","/**\n * @file Cartapus core file, dispatches events based on [data-cartapus] elements' visibility in the viewport.\n * @author Jordan Thiervoz \n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n /**\n * Gets the observer configuration object for the given element.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {(undefined|Object)} The found observer object, `undefined` if not found.\n */\n findObserverForElement(el) {\n if (!el) return\n\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n /**\n * Stores a new DOM element to be watched. Creating a new `IntersectionObserver` if needed.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {Boolean} True if a new element is being watched, else false.\n */\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n /**\n * Creates a new `IntersectionObserver` with the given options. Optionally watching a given element.\n *\n * @param {(undefined|Object)} param An object containing parameters.\n * @param {(undefined|Object)} param.options An object containing the `IntersectionObserver` parameters.\n * @param {(undefined|Element)} param.element A DOM Element to start observing with the newly created observer.\n *\n * @returns {Object} An object with the related observer values.\n */\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n /**\n * This method is called on every mutation of the DOM.\n *\n * @param {Array} records A array of MutationRecords.\n *\n * @private\n * @returns {void}\n */\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Triggers the cartapus events for the given targets. If no targets are given, all the elements will trigger their events.\n *\n * @param {(undefined|Array|Element)} targets - An element or an array of elements.\n *\n * @public\n * @returns {void}\n */\n triggerEvent(targets) {\n if (targets) {\n const els = Array.isArray(targets) ? targets : [targets]\n\n for (const el of els) {\n if (el._cartapus) {\n el._cartapus.observer.unobserve(el)\n el._cartapus.observer.observe(el)\n }\n }\n\n return\n }\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Start watching a given Element. Use in case the `data-cartapus` attribute has been added after the Element has been appended to the DOM.\n *\n * @param {Element} el A DOM element to start observing.\n *\n * @returns {Boolean} Whether the Element is now being observed or not.\n */\n add(el) {\n const success = this.storeNewElement(el)\n\n if (success) el._cartapus.observer.observe(el)\n\n return success\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","Cartapus","_Emitter","options","_this","intersect","bind","_assertThisInitialized","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","Emitter","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","_proto","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","CustomEvent","dispatchEvent","event","records","_step3","_iterator3","record","type","addedNodes","addedNode","_step4","_step6","inners","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","_iterator7","_createForOfIteratorHelperLoose","_el","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","triggerEvent","targets","els","Array","isArray","_step12","_step13","_iterator13","_step14","_iterator14","add","success","destroy","disconnect","_step15","_iterator15","_step16"],"mappings":"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"} \ No newline at end of file diff --git a/dist/cartapus.modern.mjs b/dist/cartapus.modern.mjs index 96d9566..1edf986 100644 --- a/dist/cartapus.modern.mjs +++ b/dist/cartapus.modern.mjs @@ -1,2 +1,2 @@ -function t(){}t.prototype={on:function(t,e,s){var r=this.e||(this.e={});return(r[t]||(r[t]=[])).push({fn:e,ctx:s}),this},once:function(t,e,s){var r=this;function o(){r.off(t,o),e.apply(s,arguments)}return o._=e,this.on(t,o,s)},emit:function(t){for(var e=[].slice.call(arguments,1),s=((this.e||(this.e={}))[t]||[]).slice(),r=0,o=s.length;rt.threshold===e&&t.rootMargin===s)}storeNewElement(t){if(!t||!t.hasAttribute||!t.hasAttribute("data-cartapus"))return!1;if(t.dataset.cartapusThreshold||t.dataset.cartapusRootMargin){const e=this.findObserverForElement(t);if(e)e.elements.push(t),t._cartapus=e;else{const e=t.dataset.cartapusThreshold?parseFloat(t.dataset.cartapusThreshold):this.options.threshold;this.observers.push(this.createObserver({element:t,options:{threshold:e,rootMargin:t.dataset.cartapusRootMargin?t.dataset.cartapusRootMargin:this.options.rootMargin}}))}}else this.observers[0].elements.push(t),t._cartapus=this.observers[0];return!0}createObserver({options:t,element:e}={}){const s=Object.assign(this.options,t),r={observer:new IntersectionObserver(this.intersect,s),threshold:s.threshold,rootMargin:s.rootMargin,elements:e?[e]:[],once:!(!e||!e.hasAttribute("data-cartapus-once")||"false"===e.getAttribute("data-cartapus-once"))||s.once};return e&&(e._cartapus=r),r}createMutationObserver(){this.mutationObserver=new MutationObserver(this.mutate),this.mutationObserver.observe(this.options.root?this.options.root:document.body,{childList:!0,subtree:!0})}intersect(t,e){for(const s of t){if(s.isIntersecting){s.target.setAttribute("data-cartapus","visible");const t=s.target.getAttribute("data-cartapus-once");if("false"===t)continue;(s.target._cartapus.once||null!==t)&&e.unobserve(s.target)}else s.target.setAttribute("data-cartapus","hidden");this.dispatch(s)}}dispatch(t){const e={element:t.target,visible:t.isIntersecting,intersection:t},s=new CustomEvent("cartapusintersect",{detail:e});t.target.dispatchEvent(s),this.emit("intersect",e)}mutate(t){for(const e of t)if("childList"===e.type){for(const t of e.addedNodes)if(this.storeNewElement(t)&&t._cartapus.observer.observe(t),t._cartapus){const e=t.querySelectorAll("[data-cartapus]");for(const t of e)this.storeNewElement(t)&&t._cartapus&&t._cartapus.observer.observe(t)}for(const t of e.removedNodes){if(t._cartapus){const e=t._cartapus.elements.indexOf(t);t._cartapus.elements.splice(e,1),t._cartapus.observer.unobserve(t)}if(t._cartapus){const e=t.querySelectorAll("[data-cartapus]");for(const t of e)if(t._cartapus){const e=t._cartapus.elements.indexOf(t);t._cartapus.elements.splice(e,1),t._cartapus.observer.unobserve(t)}}}}}observe(){if(!this.isObserving){this.isObserving=!0;for(const t of this.observers)for(const e of t.elements)t.observer.observe(e)}}unobserve(){if(this.isObserving){this.isObserving=!1;for(const t of this.observers)for(const e of t.elements)t.observer.unobserve(e)}}destroy(){this.unobserve(),this.mutationObserver.disconnect();for(const t of this.observers){for(const e of t.elements)delete e._cartapus;t.observer.disconnect(),t.elements=[]}}}export{s as default}; +function t(){}t.prototype={on:function(t,e,s){var r=this.e||(this.e={});return(r[t]||(r[t]=[])).push({fn:e,ctx:s}),this},once:function(t,e,s){var r=this;function o(){r.off(t,o),e.apply(s,arguments)}return o._=e,this.on(t,o,s)},emit:function(t){for(var e=[].slice.call(arguments,1),s=((this.e||(this.e={}))[t]||[]).slice(),r=0,o=s.length;rt.threshold===e&&t.rootMargin===s)}storeNewElement(t){if(!t||!t.hasAttribute||!t.hasAttribute("data-cartapus"))return!1;if(t.dataset.cartapusThreshold||t.dataset.cartapusRootMargin){const e=this.findObserverForElement(t);if(e)e.elements.push(t),t._cartapus=e;else{const e=t.dataset.cartapusThreshold?parseFloat(t.dataset.cartapusThreshold):this.options.threshold;this.observers.push(this.createObserver({element:t,options:{threshold:e,rootMargin:t.dataset.cartapusRootMargin?t.dataset.cartapusRootMargin:this.options.rootMargin}}))}}else this.observers[0].elements.push(t),t._cartapus=this.observers[0];return!0}createObserver({options:t,element:e}={}){const s=Object.assign(this.options,t),r={observer:new IntersectionObserver(this.intersect,s),threshold:s.threshold,rootMargin:s.rootMargin,elements:e?[e]:[],once:!(!e||!e.hasAttribute("data-cartapus-once")||"false"===e.getAttribute("data-cartapus-once"))||s.once};return e&&(e._cartapus=r),r}createMutationObserver(){this.mutationObserver=new MutationObserver(this.mutate),this.mutationObserver.observe(this.options.root?this.options.root:document.body,{childList:!0,subtree:!0})}intersect(t,e){for(const s of t){if(s.isIntersecting){s.target.setAttribute("data-cartapus","visible");const t=s.target.getAttribute("data-cartapus-once");if("false"===t)continue;(s.target._cartapus.once||null!==t)&&e.unobserve(s.target)}else s.target.setAttribute("data-cartapus","hidden");this.dispatch(s)}}dispatch(t){const e={element:t.target,visible:t.isIntersecting,intersection:t},s=new CustomEvent("cartapusintersect",{detail:e});t.target.dispatchEvent(s),this.emit("intersect",e)}mutate(t){for(const e of t)if("childList"===e.type){for(const t of e.addedNodes)if(this.storeNewElement(t)&&t._cartapus.observer.observe(t),t._cartapus){const e=t.querySelectorAll("[data-cartapus]");for(const t of e)this.storeNewElement(t)&&t._cartapus&&t._cartapus.observer.observe(t)}for(const t of e.removedNodes){if(t._cartapus){const e=t._cartapus.elements.indexOf(t);t._cartapus.elements.splice(e,1),t._cartapus.observer.unobserve(t)}if(t._cartapus){const e=t.querySelectorAll("[data-cartapus]");for(const t of e)if(t._cartapus){const e=t._cartapus.elements.indexOf(t);t._cartapus.elements.splice(e,1),t._cartapus.observer.unobserve(t)}}}}}observe(){if(!this.isObserving){this.isObserving=!0;for(const t of this.observers)for(const e of t.elements)t.observer.observe(e)}}unobserve(){if(this.isObserving){this.isObserving=!1;for(const t of this.observers)for(const e of t.elements)t.observer.unobserve(e)}}triggerEvent(t){if(t){const e=Array.isArray(t)?t:[t];for(const t of e)t._cartapus&&(t._cartapus.observer.unobserve(t),t._cartapus.observer.observe(t))}else for(const t of this.observers)for(const e of t.elements)t.observer.unobserve(e),t.observer.observe(e)}add(t){const e=this.storeNewElement(t);return e&&t._cartapus.observer.observe(t),e}destroy(){this.unobserve(),this.mutationObserver.disconnect();for(const t of this.observers){for(const e of t.elements)delete e._cartapus;t.observer.disconnect(),t.elements=[]}}}export{s as default}; //# sourceMappingURL=cartapus.modern.mjs.map diff --git a/dist/cartapus.modern.mjs.map b/dist/cartapus.modern.mjs.map index 2367404..0d9641b 100644 --- a/dist/cartapus.modern.mjs.map +++ b/dist/cartapus.modern.mjs.map @@ -1 +1 @@ -{"version":3,"file":"cartapus.modern.mjs","sources":["../node_modules/tiny-emitter/index.js","../src/cartapus.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","/**\n * @file Cartapus core file, dispatches events based on [data-cartapus] elements' visibility in the viewport.\n * @author Jordan Thiervoz \n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n findObserverForElement(el) {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","Cartapus","Emitter","constructor","options","super","intersect","bind","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","elems","document","querySelectorAll","el","storeNewElement","findObserverForElement","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","event","CustomEvent","dispatchEvent","records","record","type","addedNode","addedNodes","inners","removedNode","removedNodes","index","indexOf","splice","destroy","disconnect"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cartapus.modern.mjs","sources":["../node_modules/tiny-emitter/index.js","../src/cartapus.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","/**\n * @file Cartapus core file, dispatches events based on [data-cartapus] elements' visibility in the viewport.\n * @author Jordan Thiervoz \n */\n\nimport Emitter from 'tiny-emitter'\n\n/**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @class\n */\nexport default class Cartapus extends Emitter {\n /**\n * Creates a new Cartapus instance, starting to watch every `[data-cartapus]` elements' visibility right away.\n *\n * Usually you will only need to instanciate Cartapus once for your whole App.\n *\n * @param {Object} [options] — User options.\n * @param {Element} [options.root=document] — The root DOM element into which [data-cartapus] targets will be watched.\n * @param {String} [options.rootMargin=\"0px\"] — A CSS margin property string defining offsets into the `root` element.\n * @param {Number} [options.threshold=0] — A number between 0 and 1 which defines the percentage of height that must be into the viewport for an element to be considered \"visible\".\n * @param {Boolean} [options.once=false] — If \"true\", elements will only toggle to \"visible\" once and never return to their \"hidden\" state.\n *\n * @extends Emitter\n * @constructor\n */\n constructor(options = {}) {\n super()\n\n this.intersect = this.intersect.bind(this)\n this.mutate = this.mutate.bind(this)\n\n // Set user options based on default options.\n const defaults = {\n root: null,\n rootMargin: '0px',\n threshold: 0,\n once: false\n }\n\n this.isObserving = false\n this.options = Object.assign(defaults, options)\n\n // Creates the main IntersectionObserver used with the default options.\n this.observers = [this.createObserver()]\n\n this.createObservers()\n this.createMutationObserver()\n this.observe()\n }\n\n /**\n * For each [data-cartapus] element, check its inner data-cartapus parameters\n * Create new IntersectionObservers accordingly if parameters differs from the main observer.\n *\n * @private\n * @returns {void}\n */\n createObservers() {\n const root = this.options.root ? this.options.root : document\n const elems = root.querySelectorAll('[data-cartapus]')\n\n for (const el of elems) {\n this.storeNewElement(el)\n }\n }\n\n /**\n * Gets the observer configuration object for the given element.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {(undefined|Object)} The found observer object, `undefined` if not found.\n */\n findObserverForElement(el) {\n if (!el) return\n\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If an observer already exists with the same threshold & the same rootMargin, add element to this observer.\n const found = this.observers.find((observer) => observer.threshold === threshold && observer.rootMargin === rootMargin)\n\n return found\n }\n\n /**\n * Stores a new DOM element to be watched. Creating a new `IntersectionObserver` if needed.\n *\n * @param {Element} el A DOM element.\n *\n * @returns {Boolean} True if a new element is being watched, else false.\n */\n storeNewElement(el) {\n if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false\n\n // If element has a custom cartapus attribute.\n if (el.dataset.cartapusThreshold || el.dataset.cartapusRootMargin) {\n const observer = this.findObserverForElement(el)\n\n if (observer) {\n observer.elements.push(el)\n\n el._cartapus = observer\n } else {\n const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold\n const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin\n\n // If no observer has the same threshold & rootMargin, create a new one with the new options.\n this.observers.push(this.createObserver({\n element: el,\n options: {\n threshold,\n rootMargin\n }\n }))\n }\n } else {\n this.observers[0].elements.push(el)\n\n el._cartapus = this.observers[0]\n }\n\n return true\n }\n\n /**\n * Creates a new `IntersectionObserver` with the given options. Optionally watching a given element.\n *\n * @param {(undefined|Object)} param An object containing parameters.\n * @param {(undefined|Object)} param.options An object containing the `IntersectionObserver` parameters.\n * @param {(undefined|Element)} param.element A DOM Element to start observing with the newly created observer.\n *\n * @returns {Object} An object with the related observer values.\n */\n createObserver({ options, element } = {}) {\n const opt = Object.assign(this.options, options)\n const observer = {\n observer: new IntersectionObserver(this.intersect, opt),\n threshold: opt.threshold,\n rootMargin: opt.rootMargin,\n elements: element ? [element] : [],\n once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once\n }\n\n if (element) element._cartapus = observer\n\n return observer\n }\n\n /**\n * Creates the MutationObserver.\n *\n * @private\n * @returns {void}\n */\n createMutationObserver() {\n this.mutationObserver = new MutationObserver(this.mutate)\n\n this.mutationObserver.observe(this.options.root ? this.options.root : document.body, {\n childList: true,\n subtree: true\n })\n }\n\n /**\n * Callback function triggered by the observers.\n * Sets the data-cartapus attribute accordingly to the visibility of the elements.\n * Triggers the custom events.\n *\n * @param {array.} entries — An array of entries that intersected with the root.\n * @param {IntersectionObserver} observer — The observer that triggered the event.\n *\n * @private\n * @returns {void}\n */\n intersect(entries, observer) {\n for (const entry of entries) {\n // Set data-cartapus attribute value either to \"visible\" or \"hidden\".\n if (entry.isIntersecting) {\n entry.target.setAttribute('data-cartapus', 'visible')\n\n const once = entry.target.getAttribute('data-cartapus-once')\n\n if (once === 'false') continue\n\n // Stop observing this element if \"once\" options it true.\n if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target)\n } else entry.target.setAttribute('data-cartapus', 'hidden')\n\n this.dispatch(entry)\n }\n }\n\n /**\n * Triggers the CustomEvent `cartapusintersect` on the entry's target.\n * Also triggers an `intersect` event on the class instance.\n *\n * @param {IntersectionObserverEntry} entry — The entry that intersected.\n *\n * @private\n * @returns {void}\n */\n dispatch(entry) {\n // Create event with details.\n const detail = {\n element: entry.target,\n visible: entry.isIntersecting,\n intersection: entry\n }\n const event = new CustomEvent('cartapusintersect', { detail })\n\n // Dispatch element and instance events.\n entry.target.dispatchEvent(event)\n this.emit('intersect', detail)\n }\n\n /**\n * This method is called on every mutation of the DOM.\n *\n * @param {Array} records A array of MutationRecords.\n *\n * @private\n * @returns {void}\n */\n mutate(records) {\n for (const record of records) {\n if (record.type === 'childList') {\n for (const addedNode of record.addedNodes) {\n const success = this.storeNewElement(addedNode)\n\n if (success) addedNode._cartapus.observer.observe(addedNode)\n\n if (addedNode._cartapus) {\n const inners = addedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n const success = this.storeNewElement(el)\n\n if (success && el._cartapus) el._cartapus.observer.observe(el)\n }\n }\n }\n\n for (const removedNode of record.removedNodes) {\n if (removedNode._cartapus) {\n const index = removedNode._cartapus.elements.indexOf(removedNode)\n\n removedNode._cartapus.elements.splice(index, 1)\n removedNode._cartapus.observer.unobserve(removedNode)\n }\n\n if (removedNode._cartapus) {\n const inners = removedNode.querySelectorAll('[data-cartapus]')\n\n for (const el of inners) {\n if (el._cartapus) {\n const index = el._cartapus.elements.indexOf(el)\n\n el._cartapus.elements.splice(index, 1)\n el._cartapus.observer.unobserve(el)\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Turns on all the observers to watch all of their related targets.\n *\n * This will trigger Cartapus events.\n *\n * @public\n * @returns {void}\n */\n observe() {\n if (this.isObserving) return\n\n this.isObserving = true\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Turns off all the observers to stop watching all of their related targets.\n *\n * @public\n * @returns {void}\n */\n unobserve() {\n if (!this.isObserving) return\n\n this.isObserving = false\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n }\n }\n }\n\n /**\n * Triggers the cartapus events for the given targets. If no targets are given, all the elements will trigger their events.\n *\n * @param {(undefined|Array|Element)} targets - An element or an array of elements.\n *\n * @public\n * @returns {void}\n */\n triggerEvent(targets) {\n if (targets) {\n const els = Array.isArray(targets) ? targets : [targets]\n\n for (const el of els) {\n if (el._cartapus) {\n el._cartapus.observer.unobserve(el)\n el._cartapus.observer.observe(el)\n }\n }\n\n return\n }\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n observer.observer.unobserve(el)\n observer.observer.observe(el)\n }\n }\n }\n\n /**\n * Start watching a given Element. Use in case the `data-cartapus` attribute has been added after the Element has been appended to the DOM.\n *\n * @param {Element} el A DOM element to start observing.\n *\n * @returns {Boolean} Whether the Element is now being observed or not.\n */\n add(el) {\n const success = this.storeNewElement(el)\n\n if (success) el._cartapus.observer.observe(el)\n\n return success\n }\n\n /**\n * Turns off observers and empty their related targets.\n *\n * @public\n * @returns {void}\n */\n destroy() {\n this.unobserve()\n this.mutationObserver.disconnect()\n\n for (const observer of this.observers) {\n for (const el of observer.elements) {\n delete el._cartapus\n }\n\n observer.observer.disconnect()\n observer.elements = []\n }\n }\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","tinyEmitter","Cartapus","Emitter","constructor","options","super","intersect","bind","mutate","isObserving","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","elems","document","querySelectorAll","el","storeNewElement","findObserverForElement","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","opt","IntersectionObserver","getAttribute","mutationObserver","body","childList","subtree","entries","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","CustomEvent","dispatchEvent","event","records","record","type","addedNodes","addedNode","inners","removedNode","removedNodes","indexOf","splice","index","triggerEvent","targets","els","Array","isArray","add","success","destroy","disconnect"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 182b4d2..de3fc85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cartapus", - "version": "1.2.3", + "version": "1.2.4", "description": "✨ Animate DOM elements as they appear in your window. A small `IntersectionObserver` wrapper and helper.", "author": "Jordan Thiervoz", "license": "MIT", diff --git a/src/cartapus.js b/src/cartapus.js index 5de8ad4..abf1191 100644 --- a/src/cartapus.js +++ b/src/cartapus.js @@ -75,7 +75,16 @@ export default class Cartapus extends Emitter { } } + /** + * Gets the observer configuration object for the given element. + * + * @param {Element} el A DOM element. + * + * @returns {(undefined|Object)} The found observer object, `undefined` if not found. + */ findObserverForElement(el) { + if (!el) return + const threshold = el.dataset.cartapusThreshold ? parseFloat(el.dataset.cartapusThreshold) : this.options.threshold const rootMargin = el.dataset.cartapusRootMargin ? el.dataset.cartapusRootMargin : this.options.rootMargin @@ -85,6 +94,13 @@ export default class Cartapus extends Emitter { return found } + /** + * Stores a new DOM element to be watched. Creating a new `IntersectionObserver` if needed. + * + * @param {Element} el A DOM element. + * + * @returns {Boolean} True if a new element is being watched, else false. + */ storeNewElement(el) { if (!el || !el.hasAttribute || !el.hasAttribute('data-cartapus')) return false @@ -118,6 +134,15 @@ export default class Cartapus extends Emitter { return true } + /** + * Creates a new `IntersectionObserver` with the given options. Optionally watching a given element. + * + * @param {(undefined|Object)} param An object containing parameters. + * @param {(undefined|Object)} param.options An object containing the `IntersectionObserver` parameters. + * @param {(undefined|Element)} param.element A DOM Element to start observing with the newly created observer. + * + * @returns {Object} An object with the related observer values. + */ createObserver({ options, element } = {}) { const opt = Object.assign(this.options, options) const observer = { @@ -200,6 +225,14 @@ export default class Cartapus extends Emitter { this.emit('intersect', detail) } + /** + * This method is called on every mutation of the DOM. + * + * @param {Array} records A array of MutationRecords. + * + * @private + * @returns {void} + */ mutate(records) { for (const record of records) { if (record.type === 'childList') { @@ -282,6 +315,51 @@ export default class Cartapus extends Emitter { } } + /** + * Triggers the cartapus events for the given targets. If no targets are given, all the elements will trigger their events. + * + * @param {(undefined|Array|Element)} targets - An element or an array of elements. + * + * @public + * @returns {void} + */ + triggerEvents(targets) { + if (targets) { + const els = Array.isArray(targets) ? targets : [targets] + + for (const el of els) { + if (el._cartapus) { + el._cartapus.observer.unobserve(el) + el._cartapus.observer.observe(el) + } + } + + return + } + + for (const observer of this.observers) { + for (const el of observer.elements) { + observer.observer.unobserve(el) + observer.observer.observe(el) + } + } + } + + /** + * Start watching a given Element. Use in case the `data-cartapus` attribute has been added after the Element has been appended to the DOM. + * + * @param {Element} el A DOM element to start observing. + * + * @returns {Boolean} Whether the Element is now being observed or not. + */ + add(el) { + const success = this.storeNewElement(el) + + if (success) el._cartapus.observer.observe(el) + + return success + } + /** * Turns off observers and empty their related targets. * diff --git a/website/dist/assets/index-5ac5bc62.js b/website/dist/assets/index-5ac5bc62.js new file mode 100644 index 0000000..262d31d --- /dev/null +++ b/website/dist/assets/index-5ac5bc62.js @@ -0,0 +1,2 @@ +(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))n(r);new MutationObserver(r=>{for(const e of r)if(e.type==="childList")for(const t of e.addedNodes)t.tagName==="LINK"&&t.rel==="modulepreload"&&n(t)}).observe(document,{childList:!0,subtree:!0});function o(r){const e={};return r.integrity&&(e.integrity=r.integrity),r.referrerpolicy&&(e.referrerPolicy=r.referrerpolicy),r.crossorigin==="use-credentials"?e.credentials="include":r.crossorigin==="anonymous"?e.credentials="omit":e.credentials="same-origin",e}function n(r){if(r.ep)return;r.ep=!0;const e=o(r);fetch(r.href,e)}})();function g(s,a){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(o,n){return o.__proto__=n,o},g(s,a)}function A(s){if(s===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return s}function M(s,a){(a==null||a>s.length)&&(a=s.length);for(var o=0,n=new Array(a);o=s.length?{done:!0}:{done:!1,value:s[n++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function y(){}y.prototype={on:function(s,a,o){var n=this.e||(this.e={});return(n[s]||(n[s]=[])).push({fn:a,ctx:o}),this},once:function(s,a,o){var n=this;function r(){n.off(s,r),a.apply(o,arguments)}return r._=a,this.on(s,r,o)},emit:function(s){for(var a=[].slice.call(arguments,1),o=((this.e||(this.e={}))[s]||[]).slice(),n=0,r=o.length;n{for(const t of r)if(t.type==="childList")for(const e of t.addedNodes)e.tagName==="LINK"&&e.rel==="modulepreload"&&o(e)}).observe(document,{childList:!0,subtree:!0});function n(r){const t={};return r.integrity&&(t.integrity=r.integrity),r.referrerpolicy&&(t.referrerPolicy=r.referrerpolicy),r.crossorigin==="use-credentials"?t.credentials="include":r.crossorigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function o(r){if(r.ep)return;r.ep=!0;const t=n(r);fetch(r.href,t)}})();function b(s,a){return b=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,o){return n.__proto__=o,n},b(s,a)}function _(s){if(s===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return s}function A(s,a){(a==null||a>s.length)&&(a=s.length);for(var n=0,o=new Array(a);n=s.length?{done:!0}:{done:!1,value:s[o++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function m(){}m.prototype={on:function(s,a,n){var o=this.e||(this.e={});return(o[s]||(o[s]=[])).push({fn:a,ctx:n}),this},once:function(s,a,n){var o=this;function r(){o.off(s,r),a.apply(n,arguments)}return r._=a,this.on(s,r,n)},emit:function(s){for(var a=[].slice.call(arguments,1),n=((this.e||(this.e={}))[s]||[]).slice(),o=0,r=n.length;o Cartapus website - + diff --git a/website/main.js b/website/main.js index 3fdc4e8..f9c5960 100644 --- a/website/main.js +++ b/website/main.js @@ -2,5 +2,5 @@ import './style.css' import Cartapus from '../bundled/cartapus' -// eslint-disable-next-line no-new -new Cartapus() +// eslint-disable-next-line no-unused-vars +const cartapus = new Cartapus()