intersection-observer-admin
Advanced tools
Comparing version 0.0.2 to 0.0.3
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class IntersectionObserverAdmin { | ||
constructor() { | ||
var IntersectionObserverAdmin = /** @class */ (function () { | ||
function IntersectionObserverAdmin() { | ||
this.DOMRef = new WeakMap(); | ||
@@ -19,11 +19,12 @@ } | ||
*/ | ||
observe(element, enterCallback, exitCallback, observerOptions, scrollableArea) { | ||
IntersectionObserverAdmin.prototype.observe = function (element, enterCallback, exitCallback, observerOptions, scrollableArea) { | ||
var _a; | ||
if (!element || !observerOptions) { | ||
return; | ||
} | ||
const { root = window } = observerOptions; | ||
var _b = observerOptions.root, root = _b === void 0 ? window : _b; | ||
// first find shared root element (window or scrollable area) | ||
const potentialRootMatch = this._findRoot(root); | ||
var potentialRootMatch = this._findRoot(root); | ||
// second if there is a matching root, find an entry with the same observerOptions | ||
let matchingEntryForRoot; | ||
var matchingEntryForRoot; | ||
if (potentialRootMatch) { | ||
@@ -33,4 +34,4 @@ matchingEntryForRoot = this._determineMatchingElements(observerOptions, potentialRootMatch); | ||
if (matchingEntryForRoot) { | ||
const { elements, intersectionObserver } = matchingEntryForRoot; | ||
elements.push({ element, enterCallback, exitCallback }); | ||
var elements = matchingEntryForRoot.elements, intersectionObserver = matchingEntryForRoot.intersectionObserver; | ||
elements.push({ element: element, enterCallback: enterCallback, exitCallback: exitCallback }); | ||
intersectionObserver.observe(element); | ||
@@ -40,10 +41,10 @@ return; | ||
// No matching entry for root in static admin, thus create new IntersectionObserver instance | ||
const newIO = new IntersectionObserver(this._setupOnIntersection(observerOptions, scrollableArea).bind(this), observerOptions); | ||
var newIO = new IntersectionObserver(this._setupOnIntersection(observerOptions, scrollableArea).bind(this), observerOptions); | ||
newIO.observe(element); | ||
const observerEntry = { | ||
elements: [{ element, enterCallback, exitCallback }], | ||
var observerEntry = { | ||
elements: [{ element: element, enterCallback: enterCallback, exitCallback: exitCallback }], | ||
intersectionObserver: newIO, | ||
observerOptions | ||
observerOptions: observerOptions | ||
}; | ||
const stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
var stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
if (potentialRootMatch) { | ||
@@ -56,6 +57,6 @@ // if share same root and need to add new entry to root match | ||
if (this.DOMRef) { | ||
this.DOMRef.set(root, { [stringifiedOptions]: observerEntry }); | ||
this.DOMRef.set(root, (_a = {}, _a[stringifiedOptions] = observerEntry, _a)); | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -70,9 +71,9 @@ * Unobserve target element and remove element from static admin | ||
*/ | ||
unobserve(target, observerOptions, scrollableArea) { | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
IntersectionObserverAdmin.prototype.unobserve = function (target, observerOptions, scrollableArea) { | ||
var matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
const { intersectionObserver, elements } = matchingRootEntry; | ||
var intersectionObserver = matchingRootEntry.intersectionObserver, elements = matchingRootEntry.elements; | ||
intersectionObserver.unobserve(target); | ||
// important to do this in reverse order | ||
for (let i = elements.length - 1; i >= 0; i--) { | ||
for (var i = elements.length - 1; i >= 0; i--) { | ||
if (elements[i] && elements[i].element === target) { | ||
@@ -84,3 +85,3 @@ elements.splice(i, 1); | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -92,5 +93,5 @@ * cleanup data structures and unobserve elements | ||
*/ | ||
destroy() { | ||
IntersectionObserverAdmin.prototype.destroy = function () { | ||
this.DOMRef = null; | ||
} | ||
}; | ||
/** | ||
@@ -103,7 +104,8 @@ * use function composition to curry observerOptions | ||
*/ | ||
_setupOnIntersection(observerOptions, scrollableArea) { | ||
return (entries) => { | ||
return this._onIntersection(observerOptions, scrollableArea, entries); | ||
IntersectionObserverAdmin.prototype._setupOnIntersection = function (observerOptions, scrollableArea) { | ||
var _this = this; | ||
return function (entries) { | ||
return _this._onIntersection(observerOptions, scrollableArea, entries); | ||
}; | ||
} | ||
}; | ||
/** | ||
@@ -118,11 +120,12 @@ * IntersectionObserver callback when element is intersecting viewport | ||
*/ | ||
_onIntersection(observerOptions, scrollableArea, ioEntries) { | ||
ioEntries.forEach(entry => { | ||
const { isIntersecting, intersectionRatio } = entry; | ||
IntersectionObserverAdmin.prototype._onIntersection = function (observerOptions, scrollableArea, ioEntries) { | ||
var _this = this; | ||
ioEntries.forEach(function (entry) { | ||
var isIntersecting = entry.isIntersecting, intersectionRatio = entry.intersectionRatio; | ||
// first determine if entry intersecting | ||
if (isIntersecting) { | ||
// then find entry's callback in static administration | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
var matchingRootEntry = _this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
matchingRootEntry.elements.some((obj) => { | ||
matchingRootEntry.elements.some(function (obj) { | ||
if (obj.element === entry.target) { | ||
@@ -141,5 +144,5 @@ // call entry's enter callback | ||
// then find entry's callback in static administration | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
var matchingRootEntry = _this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
matchingRootEntry.elements.some((obj) => { | ||
matchingRootEntry.elements.some(function (obj) { | ||
if (obj.element === entry.target) { | ||
@@ -157,3 +160,3 @@ // call entry's enter callback | ||
}); | ||
} | ||
}; | ||
/** | ||
@@ -166,7 +169,7 @@ * { root: { stringifiedOptions: { elements: []...] } } | ||
*/ | ||
_findRoot(root) { | ||
IntersectionObserverAdmin.prototype._findRoot = function (root) { | ||
if (this.DOMRef) { | ||
return this.DOMRef.get(root); | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -183,10 +186,10 @@ * Used for onIntersection callbacks and unobserving the IntersectionObserver | ||
*/ | ||
_findMatchingRootEntry(observerOptions, scrollableArea) { | ||
const { root = window } = observerOptions; | ||
const matchingRoot = this._findRoot(root); | ||
IntersectionObserverAdmin.prototype._findMatchingRootEntry = function (observerOptions, scrollableArea) { | ||
var _a = observerOptions.root, root = _a === void 0 ? window : _a; | ||
var matchingRoot = this._findRoot(root); | ||
if (matchingRoot) { | ||
const stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
var stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
return matchingRoot[stringifiedOptions]; | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -202,12 +205,13 @@ * Determine if existing elements for a given root based on passed in observerOptions | ||
*/ | ||
_determineMatchingElements(observerOptions, potentialRootMatch) { | ||
IntersectionObserverAdmin.prototype._determineMatchingElements = function (observerOptions, potentialRootMatch) { | ||
var _this = this; | ||
if (!potentialRootMatch) { | ||
return; | ||
} | ||
const matchingKey = Object.keys(potentialRootMatch).filter(key => { | ||
const { observerOptions: comparableOptions } = potentialRootMatch[key]; | ||
return this._areOptionsSame(observerOptions, comparableOptions); | ||
var matchingKey = Object.keys(potentialRootMatch).filter(function (key) { | ||
var comparableOptions = potentialRootMatch[key].observerOptions; | ||
return _this._areOptionsSame(observerOptions, comparableOptions); | ||
})[0]; | ||
return potentialRootMatch[matchingKey]; | ||
} | ||
}; | ||
/** | ||
@@ -223,6 +227,6 @@ * recursive method to test primitive string, number, null, etc and complex | ||
*/ | ||
_areOptionsSame(observerOptions, comparableOptions) { | ||
IntersectionObserverAdmin.prototype._areOptionsSame = function (observerOptions, comparableOptions) { | ||
// simple comparison of string, number or even null/undefined | ||
const type1 = Object.prototype.toString.call(observerOptions); | ||
const type2 = Object.prototype.toString.call(comparableOptions); | ||
var type1 = Object.prototype.toString.call(observerOptions); | ||
var type2 = Object.prototype.toString.call(comparableOptions); | ||
if (type1 !== type2) { | ||
@@ -235,3 +239,3 @@ return false; | ||
// complex comparison for only type of [object Object] | ||
for (const key in observerOptions) { | ||
for (var key in observerOptions) { | ||
if (observerOptions.hasOwnProperty(key)) { | ||
@@ -246,3 +250,3 @@ // recursion to check nested | ||
return true; | ||
} | ||
}; | ||
/** | ||
@@ -257,4 +261,4 @@ * Stringify observerOptions for use as a key. | ||
*/ | ||
_stringifyObserverOptions(observerOptions, scrollableArea) { | ||
const replacer = (key, value) => { | ||
IntersectionObserverAdmin.prototype._stringifyObserverOptions = function (observerOptions, scrollableArea) { | ||
var replacer = function (key, value) { | ||
if (key === 'root' && scrollableArea) { | ||
@@ -266,5 +270,6 @@ return scrollableArea; | ||
return JSON.stringify(observerOptions, replacer); | ||
} | ||
} | ||
}; | ||
return IntersectionObserverAdmin; | ||
}()); | ||
exports.default = IntersectionObserverAdmin; | ||
//# sourceMappingURL=index.js.map |
@@ -17,4 +17,4 @@ (function (global, factory) { | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class IntersectionObserverAdmin { | ||
constructor() { | ||
var IntersectionObserverAdmin = /** @class */ (function () { | ||
function IntersectionObserverAdmin() { | ||
this.DOMRef = new WeakMap(); | ||
@@ -34,11 +34,12 @@ } | ||
*/ | ||
observe(element, enterCallback, exitCallback, observerOptions, scrollableArea) { | ||
IntersectionObserverAdmin.prototype.observe = function (element, enterCallback, exitCallback, observerOptions, scrollableArea) { | ||
var _a; | ||
if (!element || !observerOptions) { | ||
return; | ||
} | ||
const { root = window } = observerOptions; | ||
var _b = observerOptions.root, root = _b === void 0 ? window : _b; | ||
// first find shared root element (window or scrollable area) | ||
const potentialRootMatch = this._findRoot(root); | ||
var potentialRootMatch = this._findRoot(root); | ||
// second if there is a matching root, find an entry with the same observerOptions | ||
let matchingEntryForRoot; | ||
var matchingEntryForRoot; | ||
if (potentialRootMatch) { | ||
@@ -48,4 +49,4 @@ matchingEntryForRoot = this._determineMatchingElements(observerOptions, potentialRootMatch); | ||
if (matchingEntryForRoot) { | ||
const { elements, intersectionObserver } = matchingEntryForRoot; | ||
elements.push({ element, enterCallback, exitCallback }); | ||
var elements = matchingEntryForRoot.elements, intersectionObserver = matchingEntryForRoot.intersectionObserver; | ||
elements.push({ element: element, enterCallback: enterCallback, exitCallback: exitCallback }); | ||
intersectionObserver.observe(element); | ||
@@ -55,10 +56,10 @@ return; | ||
// No matching entry for root in static admin, thus create new IntersectionObserver instance | ||
const newIO = new IntersectionObserver(this._setupOnIntersection(observerOptions, scrollableArea).bind(this), observerOptions); | ||
var newIO = new IntersectionObserver(this._setupOnIntersection(observerOptions, scrollableArea).bind(this), observerOptions); | ||
newIO.observe(element); | ||
const observerEntry = { | ||
elements: [{ element, enterCallback, exitCallback }], | ||
var observerEntry = { | ||
elements: [{ element: element, enterCallback: enterCallback, exitCallback: exitCallback }], | ||
intersectionObserver: newIO, | ||
observerOptions | ||
observerOptions: observerOptions | ||
}; | ||
const stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
var stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
if (potentialRootMatch) { | ||
@@ -71,6 +72,6 @@ // if share same root and need to add new entry to root match | ||
if (this.DOMRef) { | ||
this.DOMRef.set(root, { [stringifiedOptions]: observerEntry }); | ||
this.DOMRef.set(root, (_a = {}, _a[stringifiedOptions] = observerEntry, _a)); | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -85,9 +86,9 @@ * Unobserve target element and remove element from static admin | ||
*/ | ||
unobserve(target, observerOptions, scrollableArea) { | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
IntersectionObserverAdmin.prototype.unobserve = function (target, observerOptions, scrollableArea) { | ||
var matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
const { intersectionObserver, elements } = matchingRootEntry; | ||
var intersectionObserver = matchingRootEntry.intersectionObserver, elements = matchingRootEntry.elements; | ||
intersectionObserver.unobserve(target); | ||
// important to do this in reverse order | ||
for (let i = elements.length - 1; i >= 0; i--) { | ||
for (var i = elements.length - 1; i >= 0; i--) { | ||
if (elements[i] && elements[i].element === target) { | ||
@@ -99,3 +100,3 @@ elements.splice(i, 1); | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -107,5 +108,5 @@ * cleanup data structures and unobserve elements | ||
*/ | ||
destroy() { | ||
IntersectionObserverAdmin.prototype.destroy = function () { | ||
this.DOMRef = null; | ||
} | ||
}; | ||
/** | ||
@@ -118,7 +119,8 @@ * use function composition to curry observerOptions | ||
*/ | ||
_setupOnIntersection(observerOptions, scrollableArea) { | ||
return (entries) => { | ||
return this._onIntersection(observerOptions, scrollableArea, entries); | ||
IntersectionObserverAdmin.prototype._setupOnIntersection = function (observerOptions, scrollableArea) { | ||
var _this = this; | ||
return function (entries) { | ||
return _this._onIntersection(observerOptions, scrollableArea, entries); | ||
}; | ||
} | ||
}; | ||
/** | ||
@@ -133,11 +135,12 @@ * IntersectionObserver callback when element is intersecting viewport | ||
*/ | ||
_onIntersection(observerOptions, scrollableArea, ioEntries) { | ||
ioEntries.forEach(entry => { | ||
const { isIntersecting, intersectionRatio } = entry; | ||
IntersectionObserverAdmin.prototype._onIntersection = function (observerOptions, scrollableArea, ioEntries) { | ||
var _this = this; | ||
ioEntries.forEach(function (entry) { | ||
var isIntersecting = entry.isIntersecting, intersectionRatio = entry.intersectionRatio; | ||
// first determine if entry intersecting | ||
if (isIntersecting) { | ||
// then find entry's callback in static administration | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
var matchingRootEntry = _this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
matchingRootEntry.elements.some((obj) => { | ||
matchingRootEntry.elements.some(function (obj) { | ||
if (obj.element === entry.target) { | ||
@@ -156,5 +159,5 @@ // call entry's enter callback | ||
// then find entry's callback in static administration | ||
const matchingRootEntry = this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
var matchingRootEntry = _this._findMatchingRootEntry(observerOptions, scrollableArea); | ||
if (matchingRootEntry) { | ||
matchingRootEntry.elements.some((obj) => { | ||
matchingRootEntry.elements.some(function (obj) { | ||
if (obj.element === entry.target) { | ||
@@ -172,3 +175,3 @@ // call entry's enter callback | ||
}); | ||
} | ||
}; | ||
/** | ||
@@ -181,7 +184,7 @@ * { root: { stringifiedOptions: { elements: []...] } } | ||
*/ | ||
_findRoot(root) { | ||
IntersectionObserverAdmin.prototype._findRoot = function (root) { | ||
if (this.DOMRef) { | ||
return this.DOMRef.get(root); | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -198,10 +201,10 @@ * Used for onIntersection callbacks and unobserving the IntersectionObserver | ||
*/ | ||
_findMatchingRootEntry(observerOptions, scrollableArea) { | ||
const { root = window } = observerOptions; | ||
const matchingRoot = this._findRoot(root); | ||
IntersectionObserverAdmin.prototype._findMatchingRootEntry = function (observerOptions, scrollableArea) { | ||
var _a = observerOptions.root, root = _a === void 0 ? window : _a; | ||
var matchingRoot = this._findRoot(root); | ||
if (matchingRoot) { | ||
const stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
var stringifiedOptions = this._stringifyObserverOptions(observerOptions, scrollableArea); | ||
return matchingRoot[stringifiedOptions]; | ||
} | ||
} | ||
}; | ||
/** | ||
@@ -217,12 +220,13 @@ * Determine if existing elements for a given root based on passed in observerOptions | ||
*/ | ||
_determineMatchingElements(observerOptions, potentialRootMatch) { | ||
IntersectionObserverAdmin.prototype._determineMatchingElements = function (observerOptions, potentialRootMatch) { | ||
var _this = this; | ||
if (!potentialRootMatch) { | ||
return; | ||
} | ||
const matchingKey = Object.keys(potentialRootMatch).filter(key => { | ||
const { observerOptions: comparableOptions } = potentialRootMatch[key]; | ||
return this._areOptionsSame(observerOptions, comparableOptions); | ||
var matchingKey = Object.keys(potentialRootMatch).filter(function (key) { | ||
var comparableOptions = potentialRootMatch[key].observerOptions; | ||
return _this._areOptionsSame(observerOptions, comparableOptions); | ||
})[0]; | ||
return potentialRootMatch[matchingKey]; | ||
} | ||
}; | ||
/** | ||
@@ -238,6 +242,6 @@ * recursive method to test primitive string, number, null, etc and complex | ||
*/ | ||
_areOptionsSame(observerOptions, comparableOptions) { | ||
IntersectionObserverAdmin.prototype._areOptionsSame = function (observerOptions, comparableOptions) { | ||
// simple comparison of string, number or even null/undefined | ||
const type1 = Object.prototype.toString.call(observerOptions); | ||
const type2 = Object.prototype.toString.call(comparableOptions); | ||
var type1 = Object.prototype.toString.call(observerOptions); | ||
var type2 = Object.prototype.toString.call(comparableOptions); | ||
if (type1 !== type2) { | ||
@@ -250,3 +254,3 @@ return false; | ||
// complex comparison for only type of [object Object] | ||
for (const key in observerOptions) { | ||
for (var key in observerOptions) { | ||
if (observerOptions.hasOwnProperty(key)) { | ||
@@ -261,3 +265,3 @@ // recursion to check nested | ||
return true; | ||
} | ||
}; | ||
/** | ||
@@ -272,4 +276,4 @@ * Stringify observerOptions for use as a key. | ||
*/ | ||
_stringifyObserverOptions(observerOptions, scrollableArea) { | ||
const replacer = (key, value) => { | ||
IntersectionObserverAdmin.prototype._stringifyObserverOptions = function (observerOptions, scrollableArea) { | ||
var replacer = function (key, value) { | ||
if (key === 'root' && scrollableArea) { | ||
@@ -281,4 +285,5 @@ return scrollableArea; | ||
return JSON.stringify(observerOptions, replacer); | ||
} | ||
} | ||
}; | ||
return IntersectionObserverAdmin; | ||
}()); | ||
exports.default = IntersectionObserverAdmin; | ||
@@ -285,0 +290,0 @@ |
{ | ||
"name": "intersection-observer-admin", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Intersection Observer Admin for better performance", | ||
"main": "dist/intersection-observer-admin.umd.js", | ||
"module": "dist/intersection-observer-admin.es5.js", | ||
"types": "dist/types/index.d.ts", | ||
@@ -61,4 +60,4 @@ "scripts": { | ||
"tslint-plugin-prettier": "^2.0.1", | ||
"typescript": "^3.1.6" | ||
"typescript": "^3.2.0" | ||
} | ||
} |
@@ -11,3 +11,3 @@ intersection-observer-admin | ||
------------------------------------------------------------------------------ | ||
This library is used in [ember-in-viewport](https://github.com/DockYard/ember-in-viewport). This library is particularly important for re-using the IntersectionObserver API. | ||
This library is used in [ember-in-viewport](https://github.com/DockYard/ember-in-viewport) and [ember-infinity](https://github.com/ember-infinity/ember-infinity). This library is particularly important for re-using the IntersectionObserver API. | ||
@@ -45,3 +45,3 @@ Most implementations have one Intersection Observer for each target element or so called `sentinel`. However, [IntersectionObserver.observe](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/observe) can observer multiple `sentinels`. So this library will resuse the IntersectionObserver instance for another element on the page with the same set of observer options and root element. This can dramatically improve performance for pages with lots of elements and observers. | ||
// remove an element from the static administrator | ||
// add an element in a scrolling container | ||
intersectionObserverAdmin.add(element, enterCallback, exitCallback, { root, rootMargin: '0px 0px 100px 0px', threshold: 0 }, '.my-list'); | ||
@@ -48,0 +48,0 @@ |
Sorry, the diff of this file is not supported yet
38084
7
654