Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get width of (DOM) Element in Angular2

there a some similiar threads but I couldn't find a suitable answer for my needs. So that direct DOM access should be strictly avoided in angular2 I'm just wondering whats best practice for this.

What I wan't to achieve is a resize of a element based on the current width.

workitemresize.component.ts

import { Directive, ElementRef, HostListener, Renderer, Input } from '@angular/core';  @Directive({   selector: '[workItemResize]' })  export class WorkItemResizeDirective implements ngAfterViewInit {    private el: HTMLElement;   private renderer: Renderer;    constructor(el: ElementRef, public renderer: Renderer)   {      this.el = el.nativeElement;      this.renderer = renderer;   }       @HostListener('window:resize', ['$event.target'])    onResize()    {      this.resizeWorks();   }    ngAfterViewInit() {     this.resizeWorks();   }    private resizeWorks(): void {     this.renderer.setElementStyle(this.el, 'height', this.el.width); // <-- doesn't work I kow that this.el.width doesn't exist but just for demonstration purpose     this.renderer.setElementStyle(this.el, 'height', '500'); // <-- works   }  } 

projects.template.html

<div class="posts row">         <div class="work-item col-xs-12 col-sm-6 col-no-padding"  workItemResize *ngFor="let post of posts">                  <!-- show some fancy image -->                 <div class="img"  [ngStyle]="{'background-image':'url('+post.better_featured_image.source_url+')'}"></div>          </div> </div> 

Related: https://github.com/angular/angular/issues/6515

like image 431
Kevin Regenrek Avatar asked Aug 22 '16 16:08

Kevin Regenrek


People also ask

How do you find the width of a DOM element?

Use offsetWidth & offsetHeight properties of the DOM element to get its the width and height.

What is offsetWidth?

Typically, offsetWidth is a measurement in pixels of the element's CSS width, including any borders, padding, and vertical scrollbars (if rendered). It does not include the width of pseudo-elements such as ::before or ::after . If the element is hidden (for example, by setting style.

What is a native element angular?

Angular ElementRef is a wrapper around a native element inside of a View. It's simply a class that wraps native DOM elements in the browser and allows you to work with the DOM by providing the nativeElement object which exposes all the methods and properties of the native elements.


2 Answers

I don't know a way to get the width from the host element without accessing nativeElement but setting could be done like:

@HostListener('window:resize', ['$event.target'])  onResize() {    this.resizeWorks(); }  @HostBinding('style.height.px') elHeight:number;  private resizeWorks(): void {   this.elHeight = this.el.nativeElement.width; } 

If you can add an element inside your components template like

<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()">   <!-- your template here --> </div> 

then this would work without direct DOM access at all (but not after init).

like image 82
Günter Zöchbauer Avatar answered Sep 28 '22 17:09

Günter Zöchbauer


I tried out @GünterZöchbauer solution and refined it. You do not need HostListener to get bounds of div. Like with 'click' or other event (event)="function()", it will fire this function. I hope someone will find this helpful.

<div #div (window:resize)="onResize(div.getBoundingClientRect())">    <!-- your template here --> </div>   onResize() {     this.resizeWorks(); }  @HostBinding('style.height.px') elHeight:number;  private resizeWorks(): void {    this.elHeight = this.el.nativeElement.width; } 

(#div) - this is variable needed to get measurement target. It does not have to be same name as element, it can be any name.

One more way to get element dimensions is to use ElementRef class from Angular Core, but then you have to find that child element which has width and height properties. I used this in Angular 2 Maps to get container width and height, but i found out that, using this method i had to find in element tree element which had these properties and it was second child of root element. It is more messy. ElementDimensions - is just a class with height and width which I made to contain those properties.

<div (window:resize)="onResize()">    <!-- your template here --> </div>  private getContainerDimensions(): ElementDimensions{     var rootElement = this.elementRef.nativeElement;     var childElement = rootElement.firstElementChild;     var contentElement =  childElement.firstElementChild;      return {         height:contentElement.clientHeight,         width: contentElement.clientWidth     }; } 
like image 42
Imants Volkovs Avatar answered Sep 28 '22 18:09

Imants Volkovs