Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Element height and width change detection in Angular 2

Tags:

angular

I was looking for a solution, but nothing found (only articles about (window:resize), but it is not I am looking for).

How to detect element size change in Angular 2?

<div #myElement (sizeChanged)="callback()" /> 

I want to use some CSS animations and detect element's height and width changes.

like image 253
Nickon Avatar asked Nov 17 '16 15:11

Nickon


People also ask

How to detect screen width in Angular?

Import HostListener API from '@angular/core' package, define variables get screen width and getScreenHeight, use the HostListener to bind window to resize event to get the screen size and width on window resize. Update the code in src/app/app.

How do I find the size of a TS file?

Use window. innerWidth and window. innerHeight to get the current screen size of a page.


2 Answers

Edit: Modern answer

Modern browsers support the ResizeObserver API. The API has been out for a number of years and is now widely supported. Unfortunately, Edge only supports it now that it's on Chromium. If that matters to you, look at the old answer or use a polyfill.

If you're interested, here goes. You want to create a ResizeObserver object and call observe on it. In this example, the blue block keeps resizing as we cycle the text and padding. The current size of the element is added to the unordered list.

const btn = document.getElementById('btn'); const container = document.getElementById('container'); const output = document.getElementById('output'); btn.onclick = () => {   if (index > 2) {     if (container.className === '') {       container.className = 'high';     } else {       container.className = '';     }     index = 0;   }   container.innerText = values[index++]; }  let index = 0; const values = [   'Short',   'Longer text',   'Very much longer text of the kind that will fill a large container', ];  function createEntry(text) { const li = document.createElement('li');     li.innerText = text;     output.appendChild(li); }  let obs = new ResizeObserver(entries => {   console.log(entries)   for (let entry of entries) {     const cr = entry.contentRect;     createEntry(`Element size: ${cr.width}px x ${cr.height}px`)   } }); obs.observe(container);
#container {   display: inline-block;   background: lightblue; } .high {   padding: 1rem; }
<div>   <button id="btn">Cycle</button> </div> <div id="container">Test This</div> <ul id="output"> </ul>

Original answer

The problem is not even an Angular problem. More generally, how do you detect size changes in any element other than window? There is an onresize event, but this is only triggered for window and there are no other obvious solutions.

The general way that many approach this, is to set an interval of, say, 100ms and check the width and height of the div to detect a change. As horrible as it sounds, this is the most common approach.

From this answer to the more general question, there is a library to do this using only events: http://marcj.github.io/css-element-queries/. Supposedly, it's quite good. You would use the ResizeSensor to get what you're looking for.

Unless of course, you're only expecting the div to resize when the window does. Then onresize is what you're looking for.

like image 196
Cobus Kruger Avatar answered Sep 18 '22 15:09

Cobus Kruger


Detecting a change in any element of the angular component. We can use a ResizeObserver (class from import ResizeObserver from 'resize-observer-polyfill'; ) without library.

here is my implementation:

Import:

import ResizeObserver from 'resize-observer-polyfill'; 

Implementation:

@ViewChild('divId') //eg: <div #divId><div>  public agNote: ElementRef; //Element Reference on which the callback needs to be added  /**    * this will bind resize observer to the target element    */   elementObserver() {     var ro = new ResizeObserver(entries => {       for (let entry of entries) {         const cr = entry.contentRect;         console.log('Element:', entry.target);         console.log(`Element size: ${cr.width}px x ${cr.height}px`);         console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);         console.log($event);        }     });      // Element for which to observe height and width      ro.observe(this.agNote.nativeElement);   } 
like image 24
Sufiyan Ansari Avatar answered Sep 18 '22 15:09

Sufiyan Ansari