Polyfills the ResizeObserver API.
Installations
npm install @juggle/resize-observer
Developer
Developer Guide
Module System
CommonJS
Min. Node Version
Typescript Support
Yes
Node Version
16.14.0
NPM Version
8.3.1
Statistics
964 Stars
230 Commits
46 Forks
9 Watching
6 Branches
5 Contributors
Updated on 29 Oct 2024
Bundle Size
8.07 kB
Minified
2.95 kB
Minified + Gzipped
Languages
TypeScript (99.42%)
JavaScript (0.58%)
Total Downloads
Cumulative downloads
Total Downloads
393,569,455
Last day
-1%
748,842
Compared to previous day
Last week
4.6%
3,895,535
Compared to previous week
Last month
7.9%
16,204,471
Compared to previous month
Last year
63%
205,886,192
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Resize Observer
A minimal library which polyfills the ResizeObserver API and is entirely based on the latest 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
1npm i @juggle/resize-observer
Basic usage
1import { ResizeObserver } from '@juggle/resize-observer'; 2 3const ro = new ResizeObserver((entries, observer) => { 4 console.log('Body has resized!'); 5 observer.disconnect(); // Stop observing 6}); 7 8ro.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
1import { ResizeObserver } from '@juggle/resize-observer'; 2 3const ro = new ResizeObserver((entries, observer) => { 4 console.log('Elements resized:', entries.length); 5 entries.forEach((entry, index) => { 6 const { inlineSize: width, blockSize: height } = entry.contentBoxSize[0]; 7 console.log(`Element ${index + 1}:`, `${width}x${height}`); 8 }); 9}); 10 11const els = document.querySelectorAll('.resizes'); 12[...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).
1import { ResizeObserver } from '@juggle/resize-observer'; 2 3const ro = new ResizeObserver((entries, observer) => { 4 console.log('Elements resized:', entries.length); 5 entries.forEach((entry, index) => { 6 const [size] = entry.borderBoxSize; 7 console.log(`Element ${index + 1}:`, `${size.inlineSize}x${size.blockSize}`); 8 }); 9}); 10 11// Watch border-box 12const observerOptions = { 13 box: 'border-box' 14}; 15 16const els = document.querySelectorAll('.resizes'); 17[...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.
1import { ResizeObserver } from '@juggle/resize-observer'; 2 3const ro = new ResizeObserver((entries, observer) => { 4 console.log('Elements resized:', entries.length); 5 entries.forEach((entry, index) => { 6 const { width, height } = entry.contentRect; 7 console.log(`Element ${index + 1}:`, `${width}x${height}`); 8 }); 9}); 10 11const els = document.querySelectorAll('.resizes'); 12[...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.
1import { ResizeObserver as Polyfill } from '@juggle/resize-observer'; 2 3const ResizeObserver = window.ResizeObserver || Polyfill; 4 5// Uses native or polyfill, depending on browser support. 6const ro = new ResizeObserver((entries, observer) => { 7 console.log('Something has resized!'); 8});
To improve this even more, you could use dynamic imports to only load the file when the polyfill is required.
1(async () => { 2 if ('ResizeObserver' in window === false) { 3 // Loads polyfill asynchronously, only if required. 4 const module = await import('@juggle/resize-observer'); 5 window.ResizeObserver = module.ResizeObserver; 6 } 7 // Uses native or polyfill, depending on browser support. 8 const ro = new ResizeObserver((entries, observer) => { 9 console.log('Something has resized!'); 10 }); 11})();
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.
1import { ResizeObserver } from '@juggle/resize-observer'; 2 3const ro = new ResizeObserver((entries, observer) => { 4 // Changing the body size inside of the observer 5 // will cause a resize loop and the next observation will be skipped 6 document.body.style.width = '50%'; 7}); 8 9// Listen for errors 10window.addEventListener('error', e => console.log(e.message)); 11 12// Observe the body 13ro.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.
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 | Firefox | Opera | Edge | Edge 12-18 | IE11 IE 9-10 (with polyfills)** |
Mobile
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.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 2/22 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 16 are checked with a SAST tool
Reason
12 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
Score
2
/10
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to @juggle/resize-observer
rc-resize-observer
Resize observer for React
use-resize-observer
A React hook that allows you to use a ResizeObserver to measure an element's size.
@react-hook/size
A React hook for measuring the size of HTML elements including when they change
resize-observer-polyfill
A polyfill for the Resize Observer API