All Projects → que-etc → Resize Observer Polyfill

que-etc / Resize Observer Polyfill

Licence: mit
A polyfill for the Resize Observer API

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Resize Observer Polyfill

o9n
🖥 A screen.orientation ponyfill
Stars: ✭ 55 (-96.41%)
Mutual labels:  polyfill, ponyfill
Abortcontroller Polyfill
Polyfill for the AbortController DOM API and abortable fetch (stub that calls catch, doesn't actually abort request).
Stars: ✭ 273 (-82.16%)
Mutual labels:  polyfill, ponyfill
mini-create-react-context
(A smaller) polyfill for the react context API
Stars: ✭ 34 (-97.78%)
Mutual labels:  polyfill, ponyfill
fromentries
Object.fromEntries() ponyfill (in 6 lines)
Stars: ✭ 62 (-95.95%)
Mutual labels:  polyfill, ponyfill
Unfetch
🐕 Bare minimum 500b fetch polyfill.
Stars: ✭ 5,239 (+242.42%)
Mutual labels:  polyfill, ponyfill
Core Js
Standard Library
Stars: ✭ 15,854 (+936.21%)
Mutual labels:  polyfill, ponyfill
web-streams-polyfill
Web Streams, based on the WHATWG spec reference implementation
Stars: ✭ 198 (-87.06%)
Mutual labels:  polyfill, ponyfill
Tickedoff
Tiny library (<200B gzip) for deferring something by a "tick"
Stars: ✭ 213 (-86.08%)
Mutual labels:  polyfill, ponyfill
Resize Observer
Polyfills the ResizeObserver API.
Stars: ✭ 540 (-64.71%)
Mutual labels:  polyfill, ponyfill
Fakeindexeddb
A pure JS in-memory implementation of the IndexedDB API
Stars: ✭ 373 (-75.62%)
Mutual labels:  polyfill, ponyfill
Css Vars Ponyfill
Client-side support for CSS custom properties (aka "CSS variables") in legacy and modern browsers
Stars: ✭ 1,166 (-23.79%)
Mutual labels:  polyfill, ponyfill
Scroll Into View If Needed
Element.scrollIntoView ponyfills for things like "if-needed" and "smooth"
Stars: ✭ 811 (-46.99%)
Mutual labels:  polyfill, ponyfill
Promise Fun
Promise packages, patterns, chat, and tutorials
Stars: ✭ 3,779 (+146.99%)
Mutual labels:  polyfill, ponyfill
Clipboard Polyfill
📋 Simple copying on the web, with maximum browser compatibility.
Stars: ✭ 748 (-51.11%)
Mutual labels:  polyfill, ponyfill
Ponyfill
🦄 Like polyfill but with pony pureness
Stars: ✭ 945 (-38.24%)
Mutual labels:  polyfill, ponyfill
Webvr Polyfill
Use WebVR today, without requiring a special browser build.
Stars: ✭ 1,343 (-12.22%)
Mutual labels:  polyfill
Web Bluetooth Polyfill
Windows 10 Web Bluetooth Polyfill
Stars: ✭ 68 (-95.56%)
Mutual labels:  polyfill
Document Register Element
A stand-alone working lightweight version of the W3C Custom Elements specification
Stars: ✭ 1,123 (-26.6%)
Mutual labels:  polyfill
React Suspense Polyfill
Polyfill for the React Suspense API 😮
Stars: ✭ 99 (-93.53%)
Mutual labels:  polyfill
Polyfill
PHP polyfills
Stars: ✭ 1,333 (-12.88%)
Mutual labels:  polyfill

ResizeObserver Polyfill

Build Status

A polyfill for the Resize Observer API.

Implementation is based on the MutationObserver and uses Mutation Events as a fall back if the first one is not supported, so there will be no polling unless DOM changes. Doesn't modify observed elements. Handles CSS transitions/animations and can possibly observe changes caused by dynamic CSS pseudo-classes, e.g. by :hover.

Follows the spec and the native implementation. The size is 2.44 KiB when minified and gzipped.

Live demo (has style problems in IE10 and lower).

Installation

From NPM:

npm install resize-observer-polyfill --save-dev

From Bower: (will be removed with the next major release)

bower install resize-observer-polyfill --save-dev

Browser Support

Polyfill has been tested in the following browsers:

Build Status

NOTE: Internet Explorer 8 and its earlier versions are not supported.

Usage Example

It's recommended to use this library in the form of a ponyfill, which doesn't inflict modifications of the global object.

import ResizeObserver from 'resize-observer-polyfill';

const ro = new ResizeObserver((entries, observer) => {
    for (const entry of entries) {
        const {left, top, width, height} = entry.contentRect;

        console.log('Element:', entry.target);
        console.log(`Element's size: ${ width }px x ${ height }px`);
        console.log(`Element's paddings: ${ top }px ; ${ left }px`);
    }
});

ro.observe(document.body);

Package's main file is a ES5 UMD bundle that will be swapped with the ES6 modules version for those bundlers that are aware of the module field, e.g. for Rollup or webpack 2+.

Note: global version of the polyfill (dist/ResizeObserver.global) is deprecated and will be removed in the next major release.

Observation Strategy

As mentioned above, this implementation primarily (but not solely) relies on Mutation Observer with a fallback to Mutation Events for IE 9 and IE 10.

Speaking of Mutation Events as a fallback approach: they might not be as ugly as they are being rendered, particularly when their calls are batched, throttled and there is no need to analyze changes. Given that, they won't interrupt browser's reflow/repaint cycles (same for MutationObserver) and may even outperform Internet Explorer's implementation of MO causing little to no performance degradation. In contemporary browsers (Chrome, Firefox, etc.) Mutation Observer slows down the suite that includes 200 iterations of adding/removing elements, changing attributes and modifying text data by less than 1%. Internet Explorer gives different results with MO slowing down the same suite by 2-3% while Mutation Events show the difference of ~0.6%.

As for the reasons why other approaches, namely the iframe/object and scroll strategies, were ruled out:

  • They require the observed element to be non-statically positioned.
  • You can't apply them directly to quite a number of elements: <img>, <input>, <textarea>, <canvas>, <tr>, <tbody>, <thead>, <table>, etc. For most of them you would need to keep an extra <div> wrapper and almost all instances of the SVGGraphicsElement will be out of scope.
  • The ResizeObserver spec requires to deliver notifications when a non-empty visible element becomes hidden, i.e. when either this element directly or one of its parent nodes receive the display: none state. Same goes for when it's being removed from or added to the DOM. It's not possible to handle these cases merely by using former approaches, so you'd still need to either subscribe for DOM mutations or to continuously check the element's state.

And though every approach has its own limitations, I reckon that it'd be too much of a trade-off to have those constraints when building a polyfill.

Limitations

  • Notifications are delivered ~20ms after actual changes happen.
  • Changes caused by dynamic pseudo-classes, e.g. :hover and :focus, are not tracked. As a workaround you could add a short transition which would trigger the transitionend event when an element receives one of the former classes (example).
  • Delayed transitions will receive only one notification with the latest dimensions of an element.

Building and Testing

To build polyfill. Creates UMD bundle in the dist folder:

npm run build

To run a code style test:

npm run test:lint

Running unit tests:

npm run test:spec

To test in a browser that is not present in karma's config file:

npm run test:spec:custom

Testing against a native implementation:

npm run test:spec:native

NOTE: after you invoke spec:native and spec:custom commands head to the http://localhost:9876/debug.html page.

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].