Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect resize of any element in HTML5

What should the best practices to listen on element resize event?

I want to re-position an element (jQuery dialog in my case), once it's size changed. But I am now more interested to do in a general way to to listen to resize event, unaware of how the resize happens. It suppose to be simple until I found an element can be re-sized by

  • window resize
  • content text changes
  • children elements or their children elements resized
  • a sibling element resize (e.g. a cell in a table)
  • JavaScript changes it src(of img)/style attribute directly (or it's child's)
  • JavaScript rewrite CSS rules or stylesheet
  • native resize feature textarea or CSS3 resize
  • browser's zoom or text-enlarge
  • CSS transition or animations (by :hover or any other mean)

In the de-facto standard, there is a event window.onresize to subscribe resize on a window/frame. But there is no a standard event on the HTML content or DOM Elements.

I come across the following thought

  • DOM Level 3 event target only on window/document type
  • IE has onresize for Elements but it is IE only implementation
  • MutationObserver which replace Mutation Events, but it does not fit the need of "onresize"
  • naive JavaScript polling

MutationObserver is close(inner DOM changes), but it does not (yet) cross browser (IE10 does not support) and it generate noise, not CSS aware.

A naive JavaScript polling should work in all case, but it generate either delay or CPU waste of many poll.

like image 272
Dennis C Avatar asked Sep 05 '14 06:09

Dennis C


4 Answers

As of July 2020, ResizeObserver is still un-official in W3C nor WhatWG but it is already supported by all major browsers since support Safari 13.1 since 2020-Mar-24.


FYI, there's a spec for a new ResizeObserver API. Chrome seems to be the only browser that has implemented it as of Aug 2018 (see caniuse.com), but there's at least one polyfill you can use now (which uses MutationObserver).

like image 134
Clint Harris Avatar answered Oct 12 '22 22:10

Clint Harris


Yes there is not simple solution, that's not good.

I've found something very useful for this.: cross browser event based element resize

It's tricky, appending some needed html to the element that have to be listened and detects scrolling event.

Some html example from that page:

<div class="resize-triggers">
    <div class="expand-trigger"><div></div></div>
    <div class="contract-trigger"></div>
</div>

Also Some JS:

var myElement = document.getElementById('my_element'),
    myResizeFn = function(){
        /* do something on resize */
    };
addResizeListener(myElement, myResizeFn);
removeResizeListener(myElement, myResizeFn);

But it works for elements those are able to have children, not for self-closing tags.

You can see the demo http://jsfiddle.net/3QcnQ/67/

like image 37
George Garchagudashvili Avatar answered Oct 12 '22 23:10

George Garchagudashvili


Well, there is a easy library for that. Although there's nothing official how to listen on dimension changes of all types of elements and only window supports it at the moment we have luckily a polifill for that that works very accurate and supports all browsers even inclusive IE6+.

https://github.com/marcj/css-element-queries

You can find there a class ResizeSensor. To setup a listener on a element you can just do:

new ResizeSensor($('.myelements'), function() {
    console.log('changed');
});
like image 2
Marc J. Schmidt Avatar answered Oct 12 '22 22:10

Marc J. Schmidt


Given yourelement, when the size changes (ex. a text translation took place) you can doyourstuff(), including
ro.unobserve(yourelement);

  var inilen = yourelement.offsetWidth;
  var ro = new ResizeObserver( entries => {
    for (let entry of entries) {
      const cr = entry.contentRect;
      if (inilen !== cr.width) {
        doyourstuff();        
      }
    }
  });

  ro.observe(<your element>);
like image 1
paulo carraca Avatar answered Oct 12 '22 23:10

paulo carraca