From 7cea9d3e1068648dcf7e699760e37c986cb94868 Mon Sep 17 00:00:00 2001 From: Jordy Date: Tue, 31 Jan 2023 12:38:38 +0100 Subject: [PATCH] :bug: Fix bug with once constructor parameter not being taken into account --- README.md | 80 +++++++++++++-------------- bundled/cartapus.js | 2 +- dist/cartapus.js | 2 +- dist/cartapus.js.map | 2 +- dist/cartapus.mjs | 2 +- dist/cartapus.mjs.map | 2 +- dist/cartapus.modern.mjs | 2 +- dist/cartapus.modern.mjs.map | 2 +- package.json | 2 +- src/cartapus.js | 18 +++++- website/dist/assets/index-4c6acdda.js | 2 + website/dist/assets/index-c436fa94.js | 2 - website/dist/index.html | 2 +- website/main.js | 31 ----------- 14 files changed, 66 insertions(+), 85 deletions(-) create mode 100644 website/dist/assets/index-4c6acdda.js delete mode 100644 website/dist/assets/index-c436fa94.js diff --git a/README.md b/README.md index 7ada733..0680628 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# cartapus.js +# cartapus [![npm](https://img.shields.io/npm/v/cartapus.svg)](https://www.npmjs.com/package/cartapus) [![bundlephobia](https://img.shields.io/bundlephobia/minzip/cartapus?label=bundle%20size)](https://bundlephobia.com/result?p=cartapus) ![NpmLicense](https://img.shields.io/npm/l/cartapus.svg) -✨ Animate DOM elements as they appear in your window. +✨ Animate DOM elements as they appear in your window. A small `IntersectionObserver` wrapper and helper. -*"On me voit. On me voit plus. On me voit un peu, on me voit plus." - Cartapus (2002)* - -## What is cartapus.js ? +## What is cartapus ? cartapus is a library designed to help you manage detection of elements in the browser's viewport. @@ -15,6 +13,8 @@ The goal of cartapus is to provide a **quick** and **easy to use** solution to t Cartapus also watches DOM modifications to start observing newly added elements automatically (and also to stop observing freshly removed element) using the `MutationObserver` API. +--- + ## Getting started ### Install it @@ -23,9 +23,9 @@ Cartapus also watches DOM modifications to start observing newly added elements $ npm i cartapus ``` -### Use it +### Initialize it -Initialize the library with a single line of JavaScript : +Initialize the library in your codebase : ```javascript import Cartapus from 'cartapus' @@ -33,14 +33,20 @@ import Cartapus from 'cartapus' const cartapus = new Cartapus() ``` +### Use it + Now, add `data-cartapus` attribute to any element you need to observe : ```html
``` +### Animate + When this element will be visible in the viewport, its attribute will switch to `data-cartapus="visible"`. Allowing you to adapt your CSS to easily animate this element. +An invisible element will have its attribute set to `data-cartapus="hidden"`. + Here is a fade in example : ```css @@ -56,9 +62,9 @@ Here is a fade in example : } ``` -## Options +--- -You can customize visibility detection by providing options to the Cartapus constructor. +## Options Here are all the available options : @@ -73,8 +79,6 @@ const cartapus = new Cartapus({ > `root`, `rootMargin` and `threshold` are all three related to the `IntersectionObserver` API. You can have more information about these parameters by consulting the [official documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver). -### In details - | Option | Type | Default | Description | | -------------- | ----------- | ------- | ----------- | | **root** | Element | `null` *(entire viewport)* | The root DOM element into which `[data-cartapus]` targets will be observed. Default is set to `null`, which is equivalent to the entire viewport. (More information [here](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root)) | @@ -82,45 +86,37 @@ const cartapus = new Cartapus({ | **threshold** | number | `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". (More information [here](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/thresholds)) | | **once** | boolean | `false` | If `true`, elements that are `visible` will never return to their `hidden` state even if they disappear from the `root`. | +--- + ## Events Cartapus will trigger events when an element changes its state to `visible` or `hidden`. > Events are called for **all** elements **immediately** after initializing Cartapus, providing you their *initial visibility state*. -### Instance event +To listen to the events, use the following methods : -To listen to the `intersect` event, use the following : - -```javascript +```js +// Watch intersections instance-wide cartapus.on('intersect', ({ element, visible, intersection }) => { // `element` just switched its visibility }) + +// Watch intersection per element +el.addEventListener('cartapusintersect', ({ detail }) => { + // `detail.element` just switched its visibility +}) ``` -Some useful parameters are given : +Some parameters are given to these callbacks : - `element` : The `Element` that triggered the event. - `visible` : Whether the element is visible or not (same as its `data-cartapus` value). - `intersection` : The `IntersectionObserverEntry` instance. -### Element event - -You can also listen to an event on specific elements, as following : - -```javascript -const el = document.querySelector('.box') - -el.addEventListener('cartapusintersect', ({ detail }) => { - // `detail.element` just switched its visibility -}) -``` +> `detail` contains exactly the same properties as given in the instance event (`element`, `visible` and `intersection`). -`detail` contains exactly the same properties as given in the instance event : - -- `detail.element` : The `Element` that triggered the event. -- `detail.visible` : Whether the element is visible or not (same as its `data-cartapus` value). -- `detail.intersection` : The `IntersectionObserverEntry` instance. +--- ## Advanced usage @@ -131,8 +127,7 @@ Or you may want to *prevent* a specific element *from going back* to its `hidden Some additional attributes are available to allow both of those cases, overriding the default options for this specific element : ```html -
@@ -141,7 +136,9 @@ Some additional attributes are available to allow both of those cases, overridin - `data-cartapus-threshold` : overrides the `threshold` option. *Ie : this element will be visible when 50% of its height is visible.* - `data-cartapus-root-margin` : overrides the `rootMargin` option. *Ie : the bottom bounding box of this element will be shrunk by 200px.* -- `data-cartapus-once` : overrides the `once` option. *Ie : this element will switch to `visible`, then never switch back to `hidden` again.* +- `data-cartapus-once` : overrides the `once` option. *Ie : this element will switch to `visible`, then never switch back to `hidden` again.* To turn off the `once` option, use it like this : `data-cartapus-once="false"`. + +--- ## Methods @@ -149,7 +146,7 @@ Some methods are available, to turn on/off Cartapus programmatically : ### `.destroy()` -Stops observing **all** `[data-cartapus]` elements. And disconnects all the `IntersectionObservers`. +Stops observing **all** `[data-cartapus]` elements. And disconnects all the `IntersectionObservers` along with the `MutationObserver`. ### `.unobserve()` @@ -161,15 +158,16 @@ Starts observing **all** `[data-cartapus]` elements. > This method triggers instantly the `events` for **every** element. +--- + ## Browser support Cartapus supports **all recent major versions** of the modern browsers. Internally, Cartapus uses the `IntersectionObserver` and `MutationObserver` APIs to observe elements. You can have more details about compatibility by consulting CanIuse : -- [IntersectionObserver](https://caniuse.com/#feat=intersectionobserver). -- [MutationObserver](https://caniuse.com/#feat=mutationobserver). +- [IntersectionObserver](https://caniuse.com/#feat=intersectionobserver) +- [MutationObserver](https://caniuse.com/#feat=mutationobserver) -## Todo +--- -- [ ] Implement `add` and `remove` methods to add/remove specific items to/from the watched list. -- [ ] Add a parameter to `.reset()` method to prevent the already visible items with `once = true` to reset their state. +*"On me voit. On me voit plus. On me voit un peu, on me voit plus." - Cartapus (2002)* \ No newline at end of file diff --git a/bundled/cartapus.js b/bundled/cartapus.js index 38595f1..aaec10e 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,o=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[s++]}}}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 s(){}s.prototype={on:function(e,t,r){var o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var o=this;function s(){o.off(e,s),t.apply(r,arguments)}return s._=t,this.on(e,s,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),o=0,s=r.length;oe.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,o=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[s++]}}}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 s(){}s.prototype={on:function(e,t,r){var o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var o=this;function s(){o.off(e,s),t.apply(r,arguments)}return s._=t,this.on(e,s,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),o=0,s=r.length;oe.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.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.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 }\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 // Stop observing this element if \"once\" options it true.\n if (entry.target.hasAttribute('data-cartapus-once')) 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 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 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 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 * 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 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 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","Cartapus","options","_this","intersect","bind","_assertThisInitialized","mutate","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","_proto","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","_createForOfIteratorHelperLoose","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","event","CustomEvent","dispatchEvent","records","_step3","_iterator3","record","type","_step4","_iterator4","addedNodes","addedNode","_step6","_iterator6","_step5","_iterator5","removedNodes","removedNode","index","indexOf","splice","_step7","_iterator7","_index","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","_step11","_iterator11","destroy","disconnect","_step12","_iterator12","_step13","_iterator13","Emitter"],"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 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.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 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 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 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 * 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","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_proto","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","entry","_step2","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","event","CustomEvent","dispatchEvent","records","_step3","_iterator3","_createForOfIteratorHelperLoose","record","type","_step4","_iterator4","addedNodes","addedNode","_step6","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","inners","_iterator7","_el","_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 diff --git a/dist/cartapus.mjs b/dist/cartapus.mjs index 9d1a42d..87bbc4d 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,o=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[s++]}}}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 s(){}s.prototype={on:function(e,t,r){var o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var o=this;function s(){o.off(e,s),t.apply(r,arguments)}return s._=t,this.on(e,s,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),o=0,s=r.length;oe.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.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.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 }\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 // Stop observing this element if \"once\" options it true.\n if (entry.target.hasAttribute('data-cartapus-once')) 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 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 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 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 * 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 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 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","Object","assign","root","rootMargin","threshold","observers","createObserver","createObservers","createMutationObserver","observe","_proto","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_temp","_ref","opt","IntersectionObserver","mutationObserver","MutationObserver","body","childList","subtree","entries","_step2","_iterator2","_createForOfIteratorHelperLoose","entry","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","event","CustomEvent","dispatchEvent","records","_step3","_iterator3","record","type","_step4","_iterator4","addedNodes","addedNode","_step6","_iterator6","_step5","_iterator5","removedNodes","removedNode","index","indexOf","splice","_step7","_iterator7","_index","_step8","_iterator8","_step9","_iterator9","_step10","_iterator10","_step11","_iterator11","destroy","disconnect","_step12","_iterator12","_step13","_iterator13","Emitter"],"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 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.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 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 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 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 * 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","_step","elems","document","querySelectorAll","_iterator","done","storeNewElement","value","findObserverForElement","el","dataset","cartapusThreshold","parseFloat","cartapusRootMargin","find","observer","hasAttribute","elements","_cartapus","element","_proto","_temp","_ref","opt","IntersectionObserver","getAttribute","mutationObserver","MutationObserver","body","childList","subtree","entries","entry","_step2","isIntersecting","target","setAttribute","unobserve","dispatch","detail","visible","intersection","event","CustomEvent","dispatchEvent","records","_step3","_iterator3","_createForOfIteratorHelperLoose","record","type","_step4","_iterator4","addedNodes","addedNode","_step6","_iterator6","_step5","removedNodes","_iterator5","removedNode","index","indexOf","splice","_step7","inners","_iterator7","_el","_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 diff --git a/dist/cartapus.modern.mjs b/dist/cartapus.modern.mjs index 50c502c..8a4e20e 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.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]:[]};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)s.isIntersecting?(s.target.setAttribute("data-cartapus","visible"),s.target.hasAttribute("data-cartapus-once")&&e.unobserve(s.target)):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){this.storeNewElement(t)&&t._cartapus.observer.observe(t);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)}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(){for(const t of this.observers)for(const e of t.elements)t.observer.observe(e)}unobserve(){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.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){this.storeNewElement(t)&&t._cartapus.observer.observe(t);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)}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}; //# sourceMappingURL=cartapus.modern.mjs.map diff --git a/dist/cartapus.modern.mjs.map b/dist/cartapus.modern.mjs.map index b0cc385..39817b5 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.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.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 }\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 // Stop observing this element if \"once\" options it true.\n if (entry.target.hasAttribute('data-cartapus-once')) 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 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 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 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 * 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 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 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","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","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 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.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 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 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 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 * 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 diff --git a/package.json b/package.json index c58109b..fd7e410 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cartapus", - "version": "1.2.1", + "version": "1.2.2", "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 72e1500..952dac8 100644 --- a/src/cartapus.js +++ b/src/cartapus.js @@ -48,6 +48,7 @@ export default class Cartapus extends Emitter { once: false } + this.isObserving = false this.options = Object.assign(defaults, options) // Creates the main IntersectionObserver used with the default options. @@ -123,7 +124,8 @@ export default class Cartapus extends Emitter { observer: new IntersectionObserver(this.intersect, opt), threshold: opt.threshold, rootMargin: opt.rootMargin, - elements: element ? [element] : [] + elements: element ? [element] : [], + once: element && element.hasAttribute('data-cartapus-once') && element.getAttribute('data-cartapus-once') !== 'false' ? true : opt.once } if (element) element._cartapus = observer @@ -163,8 +165,12 @@ export default class Cartapus extends Emitter { if (entry.isIntersecting) { entry.target.setAttribute('data-cartapus', 'visible') + const once = entry.target.getAttribute('data-cartapus-once') + + if (once === 'false') continue + // Stop observing this element if "once" options it true. - if (entry.target.hasAttribute('data-cartapus-once')) observer.unobserve(entry.target) + if (entry.target._cartapus.once || once !== null) observer.unobserve(entry.target) } else entry.target.setAttribute('data-cartapus', 'hidden') this.dispatch(entry) @@ -243,6 +249,10 @@ export default class Cartapus extends Emitter { * @returns {void} */ observe() { + if (this.isObserving) return + + this.isObserving = true + for (const observer of this.observers) { for (const el of observer.elements) { observer.observer.observe(el) @@ -257,6 +267,10 @@ export default class Cartapus extends Emitter { * @returns {void} */ unobserve() { + if (!this.isObserving) return + + this.isObserving = false + for (const observer of this.observers) { for (const el of observer.elements) { observer.observer.unobserve(el) diff --git a/website/dist/assets/index-4c6acdda.js b/website/dist/assets/index-4c6acdda.js new file mode 100644 index 0000000..5a25d0b --- /dev/null +++ b/website/dist/assets/index-4c6acdda.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"]'))o(r);new MutationObserver(r=>{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 M(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{for(const e of r)if(e.type==="childList")for(const t of e.addedNodes)t.tagName==="LINK"&&t.rel==="modulepreload"&&a(t)}).observe(document,{childList:!0,subtree:!0});function n(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 a(r){if(r.ep)return;r.ep=!0;const e=n(r);fetch(r.href,e)}})();function f(o,s){return f=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,a){return n.__proto__=a,n},f(o,s)}function O(o){if(o===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return o}function _(o,s){(s==null||s>o.length)&&(s=o.length);for(var n=0,a=new Array(s);n=o.length?{done:!0}:{done:!1,value:o[a++]}}}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 b(){}b.prototype={on:function(o,s,n){var a=this.e||(this.e={});return(a[o]||(a[o]=[])).push({fn:s,ctx:n}),this},once:function(o,s,n){var a=this;function r(){a.off(o,r),s.apply(n,arguments)}return r._=s,this.on(o,r,n)},emit:function(o){for(var s=[].slice.call(arguments,1),n=((this.e||(this.e={}))[o]||[]).slice(),a=0,r=n.length;a{const o=document.createElement("div"),s=document.createElement("div"),n=document.createElement("p");o.classList.add("yolo"),s.classList.add("card"),s.setAttribute("data-cartapus",""),n.textContent="Am I visible ?",console.log("---------"),console.log("APPEND"),o.appendChild(s),s.appendChild(n),j.appendChild(o)},6e3);setTimeout(()=>{const o=document.querySelector(".yolo");console.log("---------"),console.log("REMOVE"),o.remove()},14e3); diff --git a/website/dist/index.html b/website/dist/index.html index cbb690c..3733715 100644 --- a/website/dist/index.html +++ b/website/dist/index.html @@ -4,7 +4,7 @@ Cartapus website - + diff --git a/website/main.js b/website/main.js index 55fa73f..3fdc4e8 100644 --- a/website/main.js +++ b/website/main.js @@ -4,34 +4,3 @@ import Cartapus from '../bundled/cartapus' // eslint-disable-next-line no-new new Cartapus() - -const wrapper = document.querySelector('.wrapper') - -console.log('Ready') - -setTimeout(() => { - const div = document.createElement('div') - const div2 = document.createElement('div') - const p = document.createElement('p') - - div.classList.add('yolo') - div2.classList.add('card') - div2.setAttribute('data-cartapus', '') - p.textContent = 'Am I visible ?' - - console.log('---------') - console.log('APPEND') - - div.appendChild(div2) - div2.appendChild(p) - wrapper.appendChild(div) -}, 6000) - -setTimeout(() => { - const test = document.querySelector('.yolo') - - console.log('---------') - console.log('REMOVE') - - test.remove() -}, 14000)