Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why was `ResizeObserver` introduced to listen to resize changes and not a simpler Element.prototype.addEventListener('resize', callback)

I'm a bit surprised that in order to listen to changes on elements dimensions (not window Object) we have to use a new interface called ResizeObserver. While it seems to do the job pretty well; it seems a bit of a departure from other element related events that can be consumed by just adding a listener.

Take for example adding an event listener to listen for the mouseover event

document.querySelector('#ele').addEventListener('mouseover', callback);

Why not simply add a new listener to the resize event on the elements?

document.querySelector('#ele').addEventListener('resize', callback);

Is it to avoid conflicts with the window resize event? If so, why not just call it differently

document.querySelector('#ele').addEventListener('elementResize', callback);

I'm aware it is easy to create a helper method to simplify the usage of the ResizeObserver. Something like that can be as simple to use as the original addEventListener approach

export const getResizeObserver = ( ele, onResize ) => {
  let obs;

  const observerInterface = {
    stop: () => { obs.unobserve( ele ); obs.disconnect() },
  };

  obs = new ResizeObserver( entries => {
    for ( const entry of entries ) {
      onResize && onResize( entry.contentRect );
    }
  } );

  obs.observe( ele );

  return observerInterface;
};

// usage to add the listener
const obs = getResizeObserver(document.querySelector('#ele'), callback);
// later to remove the listener
obs.stop();

In any case, Is there any reason, besides just api preferences and the fact that several elements can share the observer instance, that makes the ResizeObserver approach better than the addEventListener approach?

like image 822
roy riojas Avatar asked Jan 04 '18 02:01

roy riojas


People also ask

What does ResizeObserver do?

The ResizeObserver interface reports changes to the dimensions of an Element 's content or border box, or the bounding box of an SVGElement . Note: The content box is the box in which content can be placed, meaning the border box minus the padding and border width.

What does resize observer mean?

The Resize Observer API provides a performant mechanism by which code can monitor an element for changes to its size, with notifications being delivered to the observer each time the size changes.

What is resize observer polyfill?

A minimal library which polyfills the ResizeObserver API and is entirely based on the latest Draft Specification.


2 Answers

There is a discussion in this PR in which the W3C technical architecture group tries to define when to use the Observer pattern over the EventTarget. The output of this discussion is documented here, and I'm quoting the first statement:

In general, use EventTarget and notification Events, rather than an Observer pattern, unless an EventTarget can’t work well for your feature.

The advantages of using an Observer pattern over EventTarget are as follows:

  1. Instances can be customized at observation time or at creation time. The constructor for an Observer, or its observe() method, can take options allowing authors to customize what is observed for each callback. This isn’t possible with addEventListener().

  2. It’s easy to stop listening on multiple callbacks using the disconnect() or unobserve() method on the Observer object.

  3. You have the option to provide a method like takeRecords(), which immediately fetches the relevant data instead of waiting for an event to fire.

  4. Because Observers are single-purpose, you don’t need to specify an event type.

Talking specifically about the ResizeObserver, in my opinion:

  • The 2nd and 4th points aren't too relevant. It doesn't add or take anything crucial, and I think that the resize event would be a much better match here.

  • It still doesn't implement the takeRecords() method, so the 3d point irrelevant

It leaves us with the ability to customize it at the creation and observation time and allows changing these customization APIs later on without changing the Event model.

Also, there are possible performance issues or an unavoidable recursion, but I didn't find any measurements or explanations regarding them.

like image 98
Dima Kuzmich Avatar answered Oct 21 '22 11:10

Dima Kuzmich


This was proposed (and the issue is still open), but Chrome decided to ship this using the Observer model, seemingly mostly because it was 10x faster than an implementation based on events https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/z6ienONUb5A

Now why that’s true, I don’t know.

like image 5
Eric Portis Avatar answered Oct 21 '22 12:10

Eric Portis