admin管理员组

文章数量:1194371

I want to add a resize observer to a div element in my dom to give me a callback when it resizes.

I know it can be done using the ResizeObserver, but as its not supported in all browsers, i would have to add a polyfill for it.

I wanted to know if i can do the same thing using rxJS? Just observing a dom element and doing something in a callback when it resizes.

I want to add a resize observer to a div element in my dom to give me a callback when it resizes.

I know it can be done using the ResizeObserver, but as its not supported in all browsers, i would have to add a polyfill for it.

I wanted to know if i can do the same thing using rxJS? Just observing a dom element and doing something in a callback when it resizes.

Share Improve this question asked Mar 10, 2019 at 19:29 ghostCoderghostCoder 7,6559 gold badges53 silver badges74 bronze badges 2
  • I would like to refine my answer. How are you "resizing" the <div>? Is animation involved? How many elements to you want to watch for changes? – Randy Casburn Commented Mar 10, 2019 at 20:07
  • The div resizes when more data is added or some data is removed based on some actions and conditions. As of now there is only 1 element which i want to watch for resize changes. – ghostCoder Commented Mar 11, 2019 at 8:26
Add a comment  | 

3 Answers 3

Reset to default 21

I would recommend use of ResizeObserver API directly and use Polyfill to handle, in case if there are no ResizeObserver in the browser [e.g. https://www.npmjs.com/package/resize-observer-polyfill].

And I think one can create a Resize DOM Observable using ResizeObserver API pretty easily, like below:

function resizeObservable(elem) {
    return new rxjs.Observable(subscriber => {
        var ro = new ResizeObserver(entries => {
            subscriber.next(entries);
        });

        // Observe one or multiple elements
        ro.observe(elem);
        return function unsubscribe() {
            ro.unobserve(elem);
        }
    });
}

Then you can call it just like normal RxJS.

resizeObservable(document.querySelector("XXXX"))
    .pipe(
        // ...
    )
    .subscribe(entries => {
        // handle as you like
    });

Using RxJS instead of ResizeObserver directly, can have several advantages, especially, when you are going to merge observables or want to use operators.

For example, when one want to create a scroll-to-bottom button, which will only appear when it is not in the bottom. Then you can easily do that by

const toggleShowBottomBtnObs$ = rxjs.merge(
    rxjs.fromEvent(document.querySelector("XXX", "scroll"),
    resizeObservable(document.querySelector("XXX"))
)
    .pipe(
        rxjs.operators.debounceTime(200),
        rxjs.operators.map(() => isBottom()),
        rxjs.operators.distinctUntilChanged(),
    )
    .subscribe(toggleShowBtn)

Ignoring MutationObserver and animation hacks as they are not part of the question...

Perhaps in the future. But currently this limitation exists:

...resize events are only fired on (sent to) the window object (document.defaultView). Only handlers registered on the window object will receive events.

Source:https://developer.mozilla.org/en-US/docs/Web/Events/resize

Otherwise:

You are looking for the rxJS fromEvent() method for valid HTMLElement events (read: not resize).

From the docs: https://www.learnrxjs.io/operators/creation/fromevent.html

//create observable that emits click events
const source = fromEvent(document.querySelector('#myDiv'), 'click');
const subscribe = source.subscribe(evt => console.log(evt));

TypeScript version of rxJS solution from CHANist

import { Observable, Subscriber } from 'rxjs';
import ResizeObserver from 'resize-observer-polyfill';

function elementResized$(...elements: Element[]) {
    return new Observable((subscriber: Subscriber<ResizeObserverEntry[]>) => {
        const resizeObserver = new ResizeObserver(
            (entries: ResizeObserverEntry[]) => subscriber.next(entries)
        );

        elements.forEach(elem => resizeObserver.observe(elem));

        return () => resizeObserver.disconnect();
    });
}

本文标签: javascriptObserve resize of a dom element using rxJSStack Overflow