Explain Codes LogoExplain Codes Logo

How to detect DIV's dimension changed?

javascript
resize-observer
responsive-design
performance
Alex KataevbyAlex Kataev·Sep 11, 2024
TLDR

Use the ResizeObserver API to detect changes in a DIV's dimensions. It provides a callback function which can log the new dimensions every time there is a change:

const observer = new ResizeObserver(entries => { const {width, height} = entries[0].contentRect; // Our friendly log here saying "Hey, something changed!" console.log(`New size: ${width}x${height}`); }); observer.observe(document.querySelector('#divToWatch'));

This snippet will keep an eye on a DIV with the ID #divToWatch, logging its new width and height whenever it's resized. ResizeObserver has wide browser support, but remember to provide a polyfill for the rest.

Code, meet the ResizeObserver API

Utilizing ResizeObserver is like having a mini Sherlock Holmes inside your web page, constantly keeping an eye on your DIVs' sizes. It's like he's saying, "Dear Watson, the DIV's size just... ahh, elementary my dear!!!"

An example speaks a thousand words

Here’s a sample code to help clarify how ResizeObserver works:

const resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { const { width, height } = entry.contentRect; // Sherlock Holmes reporting live console.log(`The DIV has changed to: ${width}px x ${height}px.`); } }); // "Elementary!" - Sherlock Holmes resizeObserver.observe(document.getElementById('responsive-div'));

The no-browser-left-behind policy

Although ResizeObserver has good coverage, some older browsers might not support it. You can use a polyfill for these cases:

if (!('ResizeObserver' in window)) { // I guess we're going old school }

Plan B and some enhancements

When ResizeObserver is not suitable or you need extra firepower, consider alternatives and enhancements:

Sir ResizeSensor at your service

ResizeSensor, a knight from the css-element-queries library, can provide a reliable alternative:

const resizeSensor = new ResizeSensor('#myElement', function() { // The knight exclaims console.log('The kingdom has transformed!'); });

Combo power-up: ResizeObserver, window resize events, and MutationObserver

If you need to be extra sure about capturing those pesky size changes, ResizeObserver, window resize events, and MutationObserver can serve as the three musketeers of your codebase:

window.addEventListener('resize', () => _check_for_changes(element)); const mutationObserver = new MutationObserver(() => _check_for_changes(element)); // The Musketeers are on it! mutationObserver.observe(element, { childList: true, subtree: true });

Save the performance, save the world!

Remember that all these checks and callbacks can slow down your application, so be kind to your performance by using debouncing:

let timeoutId; resizeObserver = new ResizeObserver(() => { clearTimeout(timeoutId); // Our report will be ready... shortly! timeoutId = setTimeout(() => { // Doing the heavy lifting here }, 100); });

Some tips to make your life easier

A few nuggets of wisdom for implementing these:

Keep your targets in sight

Choose your selectors wisely to avoid unnecessary overhead, especially when juggling with jQuery:

const $myElement = $('#myElement'); const resizeSensor = new ResizeSensor($myElement, function() { // Bingo, another change! console.log('Element size changed!'); });

Traps and pitfalls

Avoid using methods like jQuery onresize plugins and setInterval or setTimeout checks that are too old school and unreliable. Let's keep ahead with the modern APIs, shall we?

Visualization

In a game of Ping-Pong, when the ball 🏓 hits either side of the table, the dimensions slightly change due to the force:

Ping-Pong table: [🔳🔲🔳🔲] Ball hits: [🔳🔲🏓🔲] Table with a Sensor (👀) that notices changes: [🔳🔲🔳🔲] <- 🏓 -> [🔳🔲🏓🔲] 👀 "Aha, the shape has changed!"

The Sensor (👀) is our ResizeObserver, always on standby to detect any dimension changes:

const pingPongSensor = new ResizeObserver(entries => { for (let entry of entries) { const { width, height } = entry.contentRect; console.log(`Ping-Pong table size changed to: ${width}x${height}`); } }); // "Aha! Someone's playing Ping-Pong!" pingPongSensor.observe(document.querySelector('.pingPongTable'));

Just like the ResizeObserver, the Ping-Pong Sensor is also always alert for any dimension changes to the table (DIV).