📜 ⬆️ ⬇️

We trace element resizing without setTimeout and frames

image
Probably every web developer has ever encountered the problem of tracking the resize event on a page. And if for a window any beginner can do this, then for the remaining elements this task will bring a lot of headaches. If you belong to this category of people, then welcome under cat.

There are many articles on the Internet where this problem is solved with the help of setInterval or, at best, recursive setTimeout, which constantly checks at certain intervals whether the dimensions of the specified element have changed. But in most cases, the size of the element is changed very rarely, so this method is unacceptable and, moreover, can lead to unnecessary memory waste.

On Habré, I found a solution for tracking “onresize” on an element by adding a frame inside it . This method is working and in most cases will certainly be useful. But what if for some reason you do not want to add an extra frame into the element? I want to suggest a couple more ways to track the resizing of an item.

To begin with, I will break down the cases in which the size of an element changes into categories
')

First way: DOMSubtreeModified


Most often, the need to track the size of an element occurs in order to update the state of a plug-in when content changes in a particular block. For example, update the carousel plugin after the content height inside it has changed.

To do this, there is no need to observe the resizing of the element by means of CSS, and it is enough just to track the change in the structure of the DOM inside the element.

This can be easily done using the DOMSubtreeModified event , which is triggered whenever a structure or text inside an element changes:

el.addEventListener("DOMSubtreeModified", function (e) { console.log(" : " + el.clientWidth + " X " + el.clientHeight); }, false); 

→ Browser support

Second way: transitionend


In order to track resizing through CSS, you will have to add the following styles:

 #el, #el * { /*      */ transition-property: width, height, padding, margin; /*  "  "   */ transition-duration: 1ms; } 

The list of properties, as well as the duration of the transition, can be chosen for you. It is possible that some of these properties of the element are already set or not need to apply them to all nested elements.

It turns out that with the help of CSS selectors we can flexibly indicate which elements need to track resizing (or any other animated properties).

Thus, the target block and all elements inside it will have an instantaneous transformation and as the event pops up, we can now track the transitionend event , which will work when the CSS transition ends on any child element:

 el.addEventListener("transitionend", function () { console.log(" : " + el.clientWidth + " X " + el.clientHeight); }, false); 

→ Browser support

Unfortunately, there is no transitionstart and transition or transitioninterval property, so the event is triggered only after the transition is completed, so the transition-duration value should be chosen small. But if you set transition-duration to 0, the event will not fire at all.

Conclusion


Of course, these methods will not be able to help in any situation, but I think in most cases the first or second method (and maybe both at once) will be more than enough.

I hope this article will be useful. I will be glad to justified criticism, since this is my first experience on Habré.

→ JSFiddle demo

UPD: RubaXa prompted Resize Observers .

UPD: Updated the demo , making it more visual and added a description of the second method.

Source: https://habr.com/ru/post/326150/


All Articles