Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-intersection-observer

Package Overview
Dependencies
Maintainers
1
Versions
160
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-intersection-observer - npm Package Compare versions

Comparing version 0.3.2 to 1.0.0

57

es/index.js

@@ -64,6 +64,4 @@ 'use strict';

if (_this.node) (0, _intersection.unobserve)(_this.node);
if (node) {
(0, _intersection.observe)(node, _this.handleChange, _this.props.threshold);
}
_this.node = node;
_this.observeNode();
}, _this.handleChange = function (inView) {

@@ -77,5 +75,4 @@ return _this.setState({ inView: inView });

value: function componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState.inView !== this.state.inView) {
if (!!this.props.onChange && nextState !== this.state) {
this.props.onChange(nextState.inView);
if (nextState.inView && nextProps.unobserve) {}
}

@@ -86,2 +83,8 @@ }

value: function componentDidUpdate(prevProps, prevState) {
// If a IntersectionObserver option changed, reinit the observer
if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold) {
(0, _intersection.unobserve)(this.node);
this.observeNode();
}
if (prevState.inView !== this.state.inView) {

@@ -103,12 +106,31 @@ if (this.state.inView && this.props.triggerOnce) {

}, {
key: 'render',
value: function render() {
key: 'observeNode',
value: function observeNode() {
if (!this.node) return;
var _props = this.props,
children = _props.children,
render = _props.render,
tag = _props.tag,
triggerOnce = _props.triggerOnce,
threshold = _props.threshold,
props = _objectWithoutProperties(_props, ['children', 'render', 'tag', 'triggerOnce', 'threshold']);
root = _props.root,
rootMargin = _props.rootMargin,
rootId = _props.rootId;
(0, _intersection.observe)(this.node, this.handleChange, {
threshold: threshold,
root: root,
rootMargin: rootMargin
}, rootId);
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
children = _props2.children,
render = _props2.render,
tag = _props2.tag,
triggerOnce = _props2.triggerOnce,
threshold = _props2.threshold,
root = _props2.root,
rootId = _props2.rootId,
rootMargin = _props2.rootMargin,
props = _objectWithoutProperties(_props2, ['children', 'render', 'tag', 'triggerOnce', 'threshold', 'root', 'rootId', 'rootMargin']);
var inView = this.state.inView;

@@ -138,4 +160,11 @@

triggerOnce: _propTypes2.default.bool,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering */
threshold: _propTypes2.default.number,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. */
threshold: _propTypes2.default.oneOfType([_propTypes2.default.arrayOf(_propTypes2.default.number), _propTypes2.default.number]),
/** The HTMLElement that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if null.*/
root: _propTypes2.default.object,
/** Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). */
rootMargin: _propTypes2.default.string,
/** Unique identifier for the root element - This is used to identify the IntersectionObserver instance, so it can be reused.
* If you defined a root element, without adding an id, it will create a new instance for all components. */
rootId: _propTypes2.default.string,
/** Call this function whenever the in view state changes */

@@ -142,0 +171,0 @@ onChange: _propTypes2.default.func,

@@ -8,2 +8,3 @@ "use strict";

exports.unobserve = unobserve;
exports.destroy = destroy;
var INSTANCE_MAP = new Map();

@@ -15,21 +16,44 @@ var OBSERVER_MAP = new Map();

* @param element {HTMLElement}
* @param callback {Function} - Called with inView
* @param threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param callback {Function} Called with inView
* @param options {Object} InterSection observer options
* @param options.threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param options.root {HTMLElement} It should have a unique id or data-intersection-id in order for the Observer to reused.
* @param options.rootMargin {String} The CSS margin to apply to the root element.
* @param rootId {String} Unique identifier for the root element, to enable reusing the IntersectionObserver
*/
function observe(element, callback) {
var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
threshold: 0
};
var rootId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var threshold = options.threshold,
root = options.root,
rootMargin = options.rootMargin;
if (!element || !callback) return;
var observerInstance = OBSERVER_MAP.get(threshold);
var observerId = rootMargin ? threshold + "_" + rootMargin : "" + threshold;
if (root) {
observerId = rootId ? rootId + "_" + observerId : null;
}
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : null;
if (!observerInstance) {
observerInstance = new IntersectionObserver(onChange, { threshold: threshold });
OBSERVER_MAP.set(threshold, observerInstance);
observerInstance = new IntersectionObserver(onChange, options);
if (observerId) OBSERVER_MAP.set(observerId, observerInstance);
}
INSTANCE_MAP.set(element, {
var instance = {
callback: callback,
visible: false,
threshold: threshold
});
options: options,
observerId: observerId,
observer: !observerId ? observerInstance : undefined
};
INSTANCE_MAP.set(element, instance);
observerInstance.observe(element);
return instance;
}

@@ -47,5 +71,6 @@

var _INSTANCE_MAP$get = INSTANCE_MAP.get(element),
threshold = _INSTANCE_MAP$get.threshold;
observerId = _INSTANCE_MAP$get.observerId,
observer = _INSTANCE_MAP$get.observer;
var observerInstance = OBSERVER_MAP.get(threshold);
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : observer;

@@ -58,7 +83,9 @@ if (observerInstance) {

var itemsLeft = false;
INSTANCE_MAP.forEach(function (item) {
if (item.threshold === threshold) {
itemsLeft = true;
}
});
if (observerId) {
INSTANCE_MAP.forEach(function (item, key) {
if (item.observerId === observerId && key !== element) {
itemsLeft = true;
}
});
}

@@ -68,3 +95,3 @@ if (observerInstance && !itemsLeft) {

observerInstance.disconnect();
OBSERVER_MAP.delete(threshold);
OBSERVER_MAP.delete(observerId);
}

@@ -77,2 +104,14 @@

/**
* Destroy all IntersectionObservers currently connected
**/
function destroy() {
OBSERVER_MAP.forEach(function (observer) {
observer.disconnect();
});
OBSERVER_MAP.clear();
INSTANCE_MAP.clear();
}
function onChange(changes) {

@@ -85,12 +124,17 @@ changes.forEach(function (intersection) {

var _INSTANCE_MAP$get2 = INSTANCE_MAP.get(target),
callback = _INSTANCE_MAP$get2.callback,
visible = _INSTANCE_MAP$get2.visible,
threshold = _INSTANCE_MAP$get2.threshold;
var instance = INSTANCE_MAP.get(target);
var options = instance.options;
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
var inView = void 0;
if (Array.isArray(options.threshold)) {
// If threshold is an array, check if any of them intersects. This just triggers the onChange event multiple times.
inView = options.threshold.some(function (threshold) {
return instance.visible ? intersectionRatio > threshold : intersectionRatio >= threshold;
});
} else {
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
inView = instance.visible ? intersectionRatio > options.threshold : intersectionRatio >= options.threshold;
}
var inView = visible ? intersectionRatio > threshold : intersectionRatio >= threshold;
if (isIntersecting !== undefined) {

@@ -102,10 +146,7 @@ // If isIntersecting is defined, ensure that the element is actually intersecting.

INSTANCE_MAP.set(target, {
callback: callback,
visible: inView,
threshold: threshold
});
// Update the visible value on the instance
instance.visible = inView;
if (callback) {
callback(inView);
if (instance.callback) {
instance.callback(inView);
}

@@ -118,3 +159,4 @@ }

observe: observe,
unobserve: unobserve
unobserve: unobserve,
destroy: destroy
};

@@ -64,6 +64,4 @@ 'use strict';

if (_this.node) (0, _intersection.unobserve)(_this.node);
if (node) {
(0, _intersection.observe)(node, _this.handleChange, _this.props.threshold);
}
_this.node = node;
_this.observeNode();
}, _this.handleChange = function (inView) {

@@ -77,5 +75,4 @@ return _this.setState({ inView: inView });

value: function componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState.inView !== this.state.inView) {
if (!!this.props.onChange && nextState !== this.state) {
this.props.onChange(nextState.inView);
if (nextState.inView && nextProps.unobserve) {}
}

@@ -86,2 +83,8 @@ }

value: function componentDidUpdate(prevProps, prevState) {
// If a IntersectionObserver option changed, reinit the observer
if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold) {
(0, _intersection.unobserve)(this.node);
this.observeNode();
}
if (prevState.inView !== this.state.inView) {

@@ -103,12 +106,31 @@ if (this.state.inView && this.props.triggerOnce) {

}, {
key: 'render',
value: function render() {
key: 'observeNode',
value: function observeNode() {
if (!this.node) return;
var _props = this.props,
children = _props.children,
render = _props.render,
tag = _props.tag,
triggerOnce = _props.triggerOnce,
threshold = _props.threshold,
props = _objectWithoutProperties(_props, ['children', 'render', 'tag', 'triggerOnce', 'threshold']);
root = _props.root,
rootMargin = _props.rootMargin,
rootId = _props.rootId;
(0, _intersection.observe)(this.node, this.handleChange, {
threshold: threshold,
root: root,
rootMargin: rootMargin
}, rootId);
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
children = _props2.children,
render = _props2.render,
tag = _props2.tag,
triggerOnce = _props2.triggerOnce,
threshold = _props2.threshold,
root = _props2.root,
rootId = _props2.rootId,
rootMargin = _props2.rootMargin,
props = _objectWithoutProperties(_props2, ['children', 'render', 'tag', 'triggerOnce', 'threshold', 'root', 'rootId', 'rootMargin']);
var inView = this.state.inView;

@@ -138,4 +160,11 @@

triggerOnce: _propTypes2.default.bool,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering */
threshold: _propTypes2.default.number,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. */
threshold: _propTypes2.default.oneOfType([_propTypes2.default.arrayOf(_propTypes2.default.number), _propTypes2.default.number]),
/** The HTMLElement that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if null.*/
root: _propTypes2.default.object,
/** Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). */
rootMargin: _propTypes2.default.string,
/** Unique identifier for the root element - This is used to identify the IntersectionObserver instance, so it can be reused.
* If you defined a root element, without adding an id, it will create a new instance for all components. */
rootId: _propTypes2.default.string,
/** Call this function whenever the in view state changes */

@@ -142,0 +171,0 @@ onChange: _propTypes2.default.func,

@@ -8,2 +8,3 @@ "use strict";

exports.unobserve = unobserve;
exports.destroy = destroy;
var INSTANCE_MAP = new Map();

@@ -15,21 +16,44 @@ var OBSERVER_MAP = new Map();

* @param element {HTMLElement}
* @param callback {Function} - Called with inView
* @param threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param callback {Function} Called with inView
* @param options {Object} InterSection observer options
* @param options.threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param options.root {HTMLElement} It should have a unique id or data-intersection-id in order for the Observer to reused.
* @param options.rootMargin {String} The CSS margin to apply to the root element.
* @param rootId {String} Unique identifier for the root element, to enable reusing the IntersectionObserver
*/
function observe(element, callback) {
var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
threshold: 0
};
var rootId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var threshold = options.threshold,
root = options.root,
rootMargin = options.rootMargin;
if (!element || !callback) return;
var observerInstance = OBSERVER_MAP.get(threshold);
var observerId = rootMargin ? threshold + "_" + rootMargin : "" + threshold;
if (root) {
observerId = rootId ? rootId + "_" + observerId : null;
}
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : null;
if (!observerInstance) {
observerInstance = new IntersectionObserver(onChange, { threshold: threshold });
OBSERVER_MAP.set(threshold, observerInstance);
observerInstance = new IntersectionObserver(onChange, options);
if (observerId) OBSERVER_MAP.set(observerId, observerInstance);
}
INSTANCE_MAP.set(element, {
var instance = {
callback: callback,
visible: false,
threshold: threshold
});
options: options,
observerId: observerId,
observer: !observerId ? observerInstance : undefined
};
INSTANCE_MAP.set(element, instance);
observerInstance.observe(element);
return instance;
}

@@ -47,5 +71,6 @@

var _INSTANCE_MAP$get = INSTANCE_MAP.get(element),
threshold = _INSTANCE_MAP$get.threshold;
observerId = _INSTANCE_MAP$get.observerId,
observer = _INSTANCE_MAP$get.observer;
var observerInstance = OBSERVER_MAP.get(threshold);
var observerInstance = observerId ? OBSERVER_MAP.get(observerId) : observer;

@@ -58,7 +83,9 @@ if (observerInstance) {

var itemsLeft = false;
INSTANCE_MAP.forEach(function (item) {
if (item.threshold === threshold) {
itemsLeft = true;
}
});
if (observerId) {
INSTANCE_MAP.forEach(function (item, key) {
if (item.observerId === observerId && key !== element) {
itemsLeft = true;
}
});
}

@@ -68,3 +95,3 @@ if (observerInstance && !itemsLeft) {

observerInstance.disconnect();
OBSERVER_MAP.delete(threshold);
OBSERVER_MAP.delete(observerId);
}

@@ -77,2 +104,14 @@

/**
* Destroy all IntersectionObservers currently connected
**/
function destroy() {
OBSERVER_MAP.forEach(function (observer) {
observer.disconnect();
});
OBSERVER_MAP.clear();
INSTANCE_MAP.clear();
}
function onChange(changes) {

@@ -85,12 +124,17 @@ changes.forEach(function (intersection) {

var _INSTANCE_MAP$get2 = INSTANCE_MAP.get(target),
callback = _INSTANCE_MAP$get2.callback,
visible = _INSTANCE_MAP$get2.visible,
threshold = _INSTANCE_MAP$get2.threshold;
var instance = INSTANCE_MAP.get(target);
var options = instance.options;
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
var inView = void 0;
if (Array.isArray(options.threshold)) {
// If threshold is an array, check if any of them intersects. This just triggers the onChange event multiple times.
inView = options.threshold.some(function (threshold) {
return instance.visible ? intersectionRatio > threshold : intersectionRatio >= threshold;
});
} else {
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
inView = instance.visible ? intersectionRatio > options.threshold : intersectionRatio >= options.threshold;
}
var inView = visible ? intersectionRatio > threshold : intersectionRatio >= threshold;
if (isIntersecting !== undefined) {

@@ -102,10 +146,7 @@ // If isIntersecting is defined, ensure that the element is actually intersecting.

INSTANCE_MAP.set(target, {
callback: callback,
visible: inView,
threshold: threshold
});
// Update the visible value on the instance
instance.visible = inView;
if (callback) {
callback(inView);
if (instance.callback) {
instance.callback(inView);
}

@@ -118,3 +159,4 @@ }

observe: observe,
unobserve: unobserve
unobserve: unobserve,
destroy: destroy
};
{
"name": "react-intersection-observer",
"version": "0.3.2",
"version": "1.0.0",
"description": "Monitor if a component is inside the viewport, using IntersectionObserver API",

@@ -94,4 +94,4 @@ "main": "lib/index.js",

"enzyme-to-json": "^1.5.1",
"eslint": "^4.2.0",
"eslint-config-insilico": "^4.1.0",
"eslint": "^4.3.0",
"eslint-config-insilico": "^4.1.1",
"eslint-config-prettier": "^2.3.0",

@@ -98,0 +98,0 @@ "husky": "^0.14.3",

@@ -45,3 +45,3 @@ # react-intersection-observer

Then import it in your app
Then import it in your app:

@@ -55,10 +55,13 @@ ```js

| Name | Type | Default | Required | Description |
| ---------------- | --------- | ----------------- | -------- | ----------------------------------------------------- |
| tag | String | | false | Element tag to use for the wrapping component |
| children | func/node | | false | Children should be either a function or a node |
| triggerOnce | Bool | false | true | Only trigger this method once |
| threshold | Number | 0 | false | Number between 0 and 1 indicating the the percentage that should be visible before triggering |
| onChange | Func | | false | Call this function whenever the in view state changes |
| render | Func | | false | Use render method to only render content when inView |
| Name | Type | Default | Required | Description |
| ---------------- | ----------- | ----------------- | -------- | ----------------------------------------------------- |
| children | func/node | | true | Children should be either a function or a node |
| root | HTMLElement | | false | The HTMLElement that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if null. |
| rootId | String | | false | Unique identifier for the root element - This is used to identify the IntersectionObserver instance, so it can be reused. If you defined a root element, without adding an id, it will create a new instance for all components. |
| rootMargin | String | '0px' | false | Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). |
| tag | String | 'div' | false | Element tag to use for the wrapping component |
| threshold | Number | 0 | false | Number between 0 and 1 indicating the the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. |
| triggerOnce | Bool | false | false | Only trigger this method once |
| onChange | Func | | false | Call this function whenever the in view state changes |
| render | Func | | false | Use render method to only render content when inView |

@@ -65,0 +68,0 @@ ## Example code

@@ -24,4 +24,14 @@ import React, { Component, createElement } from 'react' // eslint-disable-line no-unused-vars

triggerOnce: PropTypes.bool,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering */
threshold: PropTypes.number,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering. Can also be an array of numbers, to create multiple trigger points. */
threshold: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.number),
PropTypes.number,
]),
/** The HTMLElement that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if null.*/
root: PropTypes.object,
/** Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). */
rootMargin: PropTypes.string,
/** Unique identifier for the root element - This is used to identify the IntersectionObserver instance, so it can be reused.
* If you defined a root element, without adding an id, it will create a new instance for all components. */
rootId: PropTypes.string,
/** Call this function whenever the in view state changes */

@@ -44,6 +54,4 @@ onChange: PropTypes.func,

componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState.inView !== this.state.inView) {
if (!!this.props.onChange && nextState !== this.state) {
this.props.onChange(nextState.inView)
if (nextState.inView && nextProps.unobserve) {
}
}

@@ -53,2 +61,12 @@ }

componentDidUpdate(prevProps, prevState) {
// If a IntersectionObserver option changed, reinit the observer
if (
prevProps.rootMargin !== this.props.rootMargin ||
prevProps.root !== this.props.root ||
prevProps.threshold !== this.props.threshold
) {
unobserve(this.node)
this.observeNode()
}
if (prevState.inView !== this.state.inView) {

@@ -71,8 +89,21 @@ if (this.state.inView && this.props.triggerOnce) {

observeNode() {
if (!this.node) return
const { threshold, root, rootMargin, rootId } = this.props
observe(
this.node,
this.handleChange,
{
threshold,
root,
rootMargin,
},
rootId,
)
}
handleNode = node => {
if (this.node) unobserve(this.node)
if (node) {
observe(node, this.handleChange, this.props.threshold)
}
this.node = node
this.observeNode()
}

@@ -89,4 +120,8 @@

threshold,
root,
rootId,
rootMargin,
...props
} = this.props
const { inView } = this.state

@@ -93,0 +128,0 @@

@@ -7,19 +7,44 @@ const INSTANCE_MAP = new Map()

* @param element {HTMLElement}
* @param callback {Function} - Called with inView
* @param threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param callback {Function} Called with inView
* @param options {Object} InterSection observer options
* @param options.threshold {Number} Number between 0 and 1, indicating how much of the element should be visible before triggering
* @param options.root {HTMLElement} It should have a unique id or data-intersection-id in order for the Observer to reused.
* @param options.rootMargin {String} The CSS margin to apply to the root element.
* @param rootId {String} Unique identifier for the root element, to enable reusing the IntersectionObserver
*/
export function observe(element, callback, threshold = 0) {
export function observe(
element,
callback,
options = {
threshold: 0,
},
rootId = null,
) {
const { threshold, root, rootMargin } = options
if (!element || !callback) return
let observerInstance = OBSERVER_MAP.get(threshold)
let observerId = rootMargin ? `${threshold}_${rootMargin}` : `${threshold}`
if (root) {
observerId = rootId ? `${rootId}_${observerId}` : null
}
let observerInstance = observerId ? OBSERVER_MAP.get(observerId) : null
if (!observerInstance) {
observerInstance = new IntersectionObserver(onChange, { threshold })
OBSERVER_MAP.set(threshold, observerInstance)
observerInstance = new IntersectionObserver(onChange, options)
if (observerId) OBSERVER_MAP.set(observerId, observerInstance)
}
INSTANCE_MAP.set(element, {
const instance = {
callback,
visible: false,
threshold,
})
options,
observerId,
observer: !observerId ? observerInstance : undefined,
}
INSTANCE_MAP.set(element, instance)
observerInstance.observe(element)
return instance
}

@@ -36,4 +61,6 @@

if (INSTANCE_MAP.has(element)) {
const { threshold } = INSTANCE_MAP.get(element)
const observerInstance = OBSERVER_MAP.get(threshold)
const { observerId, observer } = INSTANCE_MAP.get(element)
const observerInstance = observerId
? OBSERVER_MAP.get(observerId)
: observer

@@ -46,7 +73,9 @@ if (observerInstance) {

let itemsLeft = false
INSTANCE_MAP.forEach(item => {
if (item.threshold === threshold) {
itemsLeft = true
}
})
if (observerId) {
INSTANCE_MAP.forEach((item, key) => {
if (item.observerId === observerId && key !== element) {
itemsLeft = true
}
})
}

@@ -56,3 +85,3 @@ if (observerInstance && !itemsLeft) {

observerInstance.disconnect()
OBSERVER_MAP.delete(threshold)
OBSERVER_MAP.delete(observerId)
}

@@ -65,2 +94,14 @@

/**
* Destroy all IntersectionObservers currently connected
**/
export function destroy() {
OBSERVER_MAP.forEach(observer => {
observer.disconnect()
})
OBSERVER_MAP.clear()
INSTANCE_MAP.clear()
}
function onChange(changes) {

@@ -70,9 +111,21 @@ changes.forEach(intersection => {

const { isIntersecting, intersectionRatio, target } = intersection
const { callback, visible, threshold } = INSTANCE_MAP.get(target)
const instance = INSTANCE_MAP.get(target)
const options = instance.options
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
let inView = visible
? intersectionRatio > threshold
: intersectionRatio >= threshold
let inView
if (Array.isArray(options.threshold)) {
// If threshold is an array, check if any of them intersects. This just triggers the onChange event multiple times.
inView = options.threshold.some(threshold => {
return instance.visible
? intersectionRatio > threshold
: intersectionRatio >= threshold
})
} else {
// Trigger on 0 ratio only when not visible. This is fallback for browsers without isIntersecting support
inView = instance.visible
? intersectionRatio > options.threshold
: intersectionRatio >= options.threshold
}
if (isIntersecting !== undefined) {

@@ -84,10 +137,7 @@ // If isIntersecting is defined, ensure that the element is actually intersecting.

INSTANCE_MAP.set(target, {
callback,
visible: inView,
threshold,
})
// Update the visible value on the instance
instance.visible = inView
if (callback) {
callback(inView)
if (instance.callback) {
instance.callback(inView)
}

@@ -101,2 +151,3 @@ }

unobserve,
destroy,
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc