README
@smoovy/observer
Easily observe states of HTML elements and the viewport.
Installation
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.onUpdate(() => {
const size = observable.offset;
console.log(`The viewport size is ${size.width}x${size.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';
const observable = observe(window).onUpdate(
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);
Listening/Unlistening for element updates
const listener = observable.onUpdate(({ bounds, offset }) => {
console.log('Element bounds:', bounds);
console.log('Element page offset:', offset);
});
// Stop listening
listener();
Updating the element state manually
observable.update();
Removing the element state from the observer
import { unobserve } from '@smoovy/observer';
unobserver(observable);
Creating a new observable controller
Sometimes you want to disable the ResizeObserver
or just want a separate stack of elements to observer. You can simply create a new ObservableController
by instantiating it:
import { ObservableController } from '@smoovy/observer';
const observer = new ObservableController({ resizeObserver: false });
const element = document.querySelector('#test');
const observable = observer.add(element);
Development commands
// Serve with parcel
npm run serve
// Build with rollup
npm run build
// Run Jest unit tests
npm run test
// Run TSLinter
npm run lint
License
See the LICENSE file for license rights and limitations (MIT).