All Projects â†’ juggle â†’ Resize Observer

juggle / Resize Observer

Licence: apache-2.0
Polyfills the ResizeObserver API.

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Resize Observer

Clipboard Polyfill
📋 Simple copying on the web, with maximum browser compatibility.
Stars: ✭ 748 (+38.52%)
Mutual labels:  api, polyfill, ponyfill
vue-resize-sensor
detect container resizing
Stars: ✭ 75 (-86.11%)
Mutual labels:  resize, element
o9n
đŸ–Ĩ A screen.orientation ponyfill
Stars: ✭ 55 (-89.81%)
Mutual labels:  polyfill, ponyfill
web-streams-polyfill
Web Streams, based on the WHATWG spec reference implementation
Stars: ✭ 198 (-63.33%)
Mutual labels:  polyfill, ponyfill
anim-event
Event Manager for Animation
Stars: ✭ 25 (-95.37%)
Mutual labels:  resize, event
event-driven-web-components-realworld-example-app
Exemplary real world application built with Vanilla JS Web Components in an Event Driven Architecture
Stars: ✭ 55 (-89.81%)
Mutual labels:  webcomponents, event
fromentries
Object.fromEntries() ponyfill (in 6 lines)
Stars: ✭ 62 (-88.52%)
Mutual labels:  polyfill, ponyfill
node-evented-command
provides simple command/event handling for evented systems like cqrs
Stars: ✭ 15 (-97.22%)
Mutual labels:  observer, event
Abortcontroller Polyfill
Polyfill for the AbortController DOM API and abortable fetch (stub that calls catch, doesn't actually abort request).
Stars: ✭ 273 (-49.44%)
Mutual labels:  polyfill, ponyfill
Google Chart
Google Charts API web components
Stars: ✭ 284 (-47.41%)
Mutual labels:  api, webcomponents
Event
The Hoa\Event library
Stars: ✭ 319 (-40.93%)
Mutual labels:  event, observer
smart-custom-element
Smart a lightweight web component library that provides capabilities for web components, such as data binding, using es6 native class inheritance. This library is focused for providing the developer the ability to write robust and native web components without the need of dependencies and an overhead of a framework.
Stars: ✭ 17 (-96.85%)
Mutual labels:  polyfill, webcomponents
signin-with-matrix
Federated sign-in component for your web app (using Matrix)
Stars: ✭ 207 (-61.67%)
Mutual labels:  webcomponents, element
github-wc-polyfill
Ensure that all GitHub and GitLab scripts required for UXP and SeaMonkey are loaded correctly
Stars: ✭ 87 (-83.89%)
Mutual labels:  polyfill, webcomponents
EventEmitter
Simple EventEmitter with multiple listeners
Stars: ✭ 19 (-96.48%)
Mutual labels:  observer, event
mini-create-react-context
(A smaller) polyfill for the react context API
Stars: ✭ 34 (-93.7%)
Mutual labels:  polyfill, ponyfill
Fakeindexeddb
A pure JS in-memory implementation of the IndexedDB API
Stars: ✭ 373 (-30.93%)
Mutual labels:  polyfill, ponyfill
Eslint Plugin Compat
Lint the browser compatibility of your code
Stars: ✭ 2,743 (+407.96%)
Mutual labels:  api, polyfill
ready
Detect element availability on the initial page load and those dynamically appended to the DOM
Stars: ✭ 77 (-85.74%)
Mutual labels:  observer, element
Doclever
做最åĨŊįš„æŽĨåŖįŽĄį†åšŗ台
Stars: ✭ 2,849 (+427.59%)
Mutual labels:  api, element

Resize Observer


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

It immediately detects when an element resizes and provides accurate sizing information back to the handler. Check out the Example Playground for more information on usage and performance.

The latest Resize Observer specification is not yet finalised and is subject to change. Any drastic changes to the specification will bump the major version of this library, as there will likely be breaking changes. Check the release notes for more information.

Installation

npm i @juggle/resize-observer

Basic usage

import { ResizeObserver } from '@juggle/resize-observer';

const ro = new ResizeObserver((entries, observer) => {
  console.log('Body has resized!');
  observer.disconnect(); // Stop observing
});

ro.observe(document.body); // Watch dimension changes on body

This will use the ponyfilled version of ResizeObserver, even if the browser supports ResizeObserver natively.

Watching multiple elements

import { ResizeObserver } from '@juggle/resize-observer';

const ro = new ResizeObserver((entries, observer) => {
  console.log('Elements resized:', entries.length);
  entries.forEach((entry, index) => {
    const { inlineSize: width, blockSize: height } = entry.contentBoxSize[0];
    console.log(`Element ${index + 1}:`, `${width}x${height}`);
  });
});

const els = document.querySelectorAll('.resizes');
[...els].forEach(el => ro.observe(el)); // Watch multiple!

Watching different box sizes

The latest standards allow for watching different box sizes. The box size option can be specified when observing an element. Options include border-box, device-pixel-content-box and content-box (default).

import { ResizeObserver } from '@juggle/resize-observer';

const ro = new ResizeObserver((entries, observer) => {
  console.log('Elements resized:', entries.length);
  entries.forEach((entry, index) => {
    const [size] = entry.borderBoxSize;
    console.log(`Element ${index + 1}:`, `${size.inlineSize}x${size.blockSize}`);
  });
});

// Watch border-box
const observerOptions = {
  box: 'border-box'
};

const els = document.querySelectorAll('.resizes');
[...els].forEach(el => ro.observe(el, observerOptions));

From the spec:

The box size properties are exposed as sequences in order to support elements that have multiple fragments, which occur in multi-column scenarios. However the current definitions of content rect and border box do not mention how those boxes are affected by multi-column layout. In this spec, there will only be a single ResizeObserverSize returned in the sequences, which will correspond to the dimensions of the first column. A future version of this spec will extend the returned sequences to contain the per-fragment size information.

Using the legacy version (contentRect)

Early versions of the API return a contentRect. This is still made available for backwards compatibility.

import { ResizeObserver } from '@juggle/resize-observer';

const ro = new ResizeObserver((entries, observer) => {
  console.log('Elements resized:', entries.length);
  entries.forEach((entry, index) => {
    const { width, height } = entry.contentRect;
    console.log(`Element ${index + 1}:`, `${width}x${height}`);
  });
});

const els = document.querySelectorAll('.resizes');
[...els].forEach(el => ro.observe(el));

Switching between native and polyfilled versions

You can check to see if the native version is available and switch between this and the polyfill to improve performance on browsers with native support.

import { ResizeObserver as Polyfill } from '@juggle/resize-observer';

const ResizeObserver = window.ResizeObserver || Polyfill;

// Uses native or polyfill, depending on browser support.
const ro = new ResizeObserver((entries, observer) => {
  console.log('Something has resized!');
});

To improve this even more, you could use dynamic imports to only load the file when the polyfill is required.

(async () => {
  if ('ResizeObserver' in window === false) {
    // Loads polyfill asynchronously, only if required.
    const module = await import('@juggle/resize-observer');
    window.ResizeObserver = module.ResizeObserver;
  }
  // Uses native or polyfill, depending on browser support.
  const ro = new ResizeObserver((entries, observer) => {
    console.log('Something has resized!');
  });
})();

Browsers with native support may be behind on the latest specification. Use entry.contentRect when switching between native and polyfilled versions.

Resize loop detection

Resize Observers have inbuilt protection against infinite resize loops.

If an element's observed box size changes again within the same resize loop, the observation will be skipped and an error event will be dispatched on the window. Elements with undelivered notifications will be considered for delivery in the next loop.

import { ResizeObserver } from '@juggle/resize-observer';

const ro = new ResizeObserver((entries, observer) => {
  // Changing the body size inside of the observer
  // will cause a resize loop and the next observation will be skipped
  document.body.style.width = '50%';
});

// Listen for errors
window.addEventListener('error', e => console.log(e.message));

// Observe the body
ro.observe(document.body);

Notification Schedule

Notifications are scheduled after all other changes have occurred and all other animation callbacks have been called. This allows the observer callback to get the most accurate size of an element, as no other changes should occur in the same frame.

resize observer notification schedule

How are differences detected?

To prevent constant polling, every frame. The DOM is queried whenever an event occurs which could cause an element to change its size. This could be when an element is clicked, a DOM Node is added, or, when an animation is running.

To cover these scenarios, there are two types of observation. The first is to listen to specific DOM events, including resize, mousedown and focus to name a few. The second is to listen for any DOM mutations that occur. This detects when a DOM node is added or removed, an attribute is modified, or, even when some text has changed.

This allows for greater idle time, when the application itself is idle.

Features

  • Inbuilt resize loop protection.
  • Supports pseudo classes :hover, :active and :focus.
  • Supports transitions and animations, including infinite and long-running.
  • Detects changes which occur during animation frame.
  • Includes support for latest draft spec - observing different box sizes.
  • Polls only when required, then shuts down automatically, reducing CPU usage.
  • Zero delay system - Notifications are batched and delivered immediately, before the next paint.

Limitations

  • Transitions with initial delays cannot be detected.*
  • Animations and transitions with long periods of no change, will not be detected.*
  • Style changes from dev tools will only be noticed if they are inline styles.*

Tested Browsers

Desktop

chrome safari ff opera edge edge IE
Chrome Safari Firefox Opera Edge Edge 12-18 IE11
IE 9-10 (with polyfills)**

Mobile

chrome safari ff opera opera mini edge samsung internet
Chrome Safari Firefox Opera Opera Mini Edge Samsung Internet

*If other interaction occurs, changes will be detected.

**IE10 requires additional polyfills for WeakMap, MutationObserver and devicePixelRatio. IE9 requires IE10 polyfills plus requestAnimationFrame. For more information, see issue here.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].