@figliolia/size-observer
Version:
Resize Observers simplified
102 lines (101 loc) • 2.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SizeObserver = void 0;
/**
* Size Observer
*
* A light-weight wrapper around the native Resize Observer API
*
* ```typescript
* import { SizeObserver } from "@figliolia/size-observer";
*
* const node = document.getElementByID("myDOMNode");
* const observer = new SizeObserver(node, {
* width: true,
* height: true,
* onChange: ({ height, width }) => {}
* });
*
* // Clean up
* observer.destroy();
* ```
*/
class SizeObserver {
constructor(node, options) {
this.width = 0;
this.height = 0;
if (!node) {
throw new Error("Element Observer: node reference is undefined");
}
this.node = node;
this.options = options;
this.initialize();
}
setOptions(options) {
let reconnect = false;
if (this.options.type !== options.type) {
reconnect = true;
}
this.options = options;
if (reconnect) {
this.destroy();
this.initialize();
}
}
initialize() {
var _a;
this.initializeLayout();
this.observer = new ResizeObserver(entries => {
let emit = false;
for (const entry of entries) {
if (this.options.type === "content-box") {
emit = this.parseBlock(entry.contentBoxSize);
}
else if (this.options.type === "device-pixel-content-box") {
emit = this.parseBlock(entry.devicePixelContentBoxSize);
}
else {
emit = this.parseBlock(entry.borderBoxSize);
}
}
if (emit) {
this.emit();
}
});
this.observer.observe(this.node, {
box: (_a = this.options.type) !== null && _a !== void 0 ? _a : "border-box",
});
}
destroy() {
this.observer.disconnect();
}
initializeLayout() {
const { height, width } = this.node.getBoundingClientRect();
this.width = width;
this.height = height;
this.emit();
}
parseBlock(entry) {
let emit = false;
const { height, width } = this.options;
for (const block of entry) {
if (block.blockSize !== this.height) {
this.height = block.blockSize;
if (height) {
emit = true;
}
}
if (block.inlineSize !== this.width) {
this.width = block.inlineSize;
if (width) {
emit = true;
}
}
}
return emit;
}
emit() {
this.options.onChange({ width: this.width, height: this.height }, this.node);
}
}
exports.SizeObserver = SizeObserver;