Daniel Yankowsky
Daniel Yankowsky

Reputation: 7016

Is there any non-polling way to detect when a DOM element's size or position have changed?

For a long time, I've been looking for a way to detect when a DOM element's size or position has changed. It could be because the window resized, or because new child elements were added to the element, or because new elements were added around this element, or because CSS rules have changed, or because the user has changed their browser's font size. There are a huge number of reasons that an element's size or position would change.

I could hook event handlers for many of those events, but I think there are cases that aren't covered. I had hoped to use MutationObservers to just watch the element's offsetWidth or clientWidth, but it looks like those only apply to DOM attributes, not Node properties (or maybe that's just what Webkit implements). So, to be truly bulletproof, it looks like I would need to run a polling loop anyway.

Is this correct? Have I missed something important? Is polling the only bulletproof way to detect when an element's size or position has changed?

Edit

To give a little more context, this isn't tied to any one particular use case. For me, it has come up time and time again. In my current situation, I was hoping to have a canvas that is set, via CSS, to be 100% width and height of its parent. I want a script to adjust the canvas's width and height properties when its offsetWidth or clientWidth changed (this is for WebGL, where the width and height properties affect the framebuffer resolution). In another project, I wanted to have an element expand in height to fill whatever remaining space was in the user's browser window. I have come across this situation time and time again and, inevitably, the solution seems to be:

  1. Listen to window.resize
  2. Hook into any code that you write that might change the DOM (or maybe use Mutation Events or Mutation Observers)
  3. Have a periodic polling operation to clean up any missed cases

(most people stop at 1, and maybe do a little of 2)

I just wanted to make sure I wasn't missing something vital.

Incidentally, in my WebGL situation, listening to window.resize is sufficient (and is somewhat preferable, because then the canvas dimensions and rendering resolution change at the same time).

Upvotes: 29

Views: 5903

Answers (3)

David Peicho
David Peicho

Reputation: 492

As of 2019, you have access to:

Upvotes: 0

Pre101
Pre101

Reputation: 2370

You might could do it with CSS animations. Check out http://developer.streak.com/2012/11/how-to-detect-dom-changes-in-css.html and similar. I suppose it won't handle all your requirements though, now that I read through it some more.

Upvotes: 9

Daniel Yankowsky
Daniel Yankowsky

Reputation: 7016

A co-worker pointed me to a technique that uses the underflow and overflow events. I haven't tried it, and I have no idea what kind of browser support there is (looks like Chrome and FireFox, and it should work in IE by synthesizing the same events that browser would look for, but I have no idea which versions support the technique).

Upvotes: 3

Related Questions