@smoovy/observer
v1.0.7
Published
Simple and easy-to-use ticker
Downloads
149
Readme
@smoovy/observer
Easily observe states of HTML elements and the viewport.
Installation
yarn add @smoovy/observer
or
npm install --save @smoovy/observer
Why?!
Operations like window.innerWidth
and element.offsetTop
will have an impact on the performance if not used properly. So this package is useful to avoid layout thrashing by batching all of the expensive calls together and only executing them if needed.
Usage
For most use cases using the exposed observe
and unobserve
methods is sufficient.
Observing the window
import { observe } from '@smoovy/observer';
const observable = observe(window);
const unlisten = observable.onChange(() => {
console.log(`The viewport size is ${observable.width}x${observable.height}`);
});
To remove the listener and observable you can simply call the the unobserve
method:
import { unobserve } from '@smoovy/observer';
// Remove update listener
unlisten();
// Remove observable from detection
unobserve(observable);
Throttling the update listener calls
This will throttle the update callback to 100ms:
import { throttle } from '@smoovy/utils/throttle';
const observable = observe(window).onChange(
throttle(() => {}, 100)
);
Updating the observable manually
observable.update();
When does a viewport update occur?
The update callback is called everytime the user triggers the resize
event on
the window
or through ResizeObserver
s change detection.
Observing an element
Observing elements works through the same API as with the window.
import { observe } from '@smoovy/observer';
const element = document.querySelector('#test');
const observable = observe(element, {
visibilityDetection: true,
resizeDetection: true
});
Listening/Unlistening for element updates
const listener = observable.onChange(({ size, coord }) => {
console.log('Element bounds:', size);
console.log('Element page offset:', coord);
});
// Stop listening
listener();
Updating the element state manually
observable.update();
Removing the element state from the observer
import { unobserve } from '@smoovy/observer';
unobserve(observable);
Listening for visibility and dimension changes separately
The onChange
callback bundles the onDimChnage
and onVisChange
callback
together. You can listen to either of those separately:
const listenerVis = observable.onVisChange(() => {
console.log('Element is now', observable.visible);
});
const listenerDim = observable.onDimChange(() => {
console.log('Element has changed size', observable.size, observable.pos);
});
Further configurations
/**
* The target to observe. Can be HTMLElement or Window
*/
target: HTMLElement | Window;
/**
* Use `getBoundingClientRect()` instead of offsetWidth etc.
*
* Default = false
*/
useBounds?: boolean;
/**
* Automatically listen for changes, resizes and updates once created
*
* Default = true
*/
autoAttach?: boolean;
/**
* Whether to use visibility detection via the IntersectionObserver API.
* You can configure it with a custom threshold.
*
* Default = false
*/
visibilityDetection?: boolean | IntersectionObserverInit;
/**
* If `visiblityDetection` is enabled, this will delay the visibile
* event by a defined number (ms)
*
* Default = 0
*/
visibilityDelay?: number;
/**
* If `visibiltiyDetection` is enabled, remove the target from the
* IntersectionObserver once it has been marked as visible
*
* Default = false
*/
detectVisibilityOnce?: boolean;
/**
* Whether to detect dimension changes via the ResizeObserver API
*
* Default = false
*/
resizeDetection?: boolean | ResizeObserverOptions;
/**
* Debounce is the number of milliseconds to wait for the next change.
* So if the delta value is below this threshold the resize event will
* be discarded and therefore the observable will not be updated.
*
* Default = 16.6
*/
resizeDebounce?: number;
License
See the LICENSE file for license rights and limitations (MIT).