Определение изменения высоты и ширины элемента в Angular 2

Я искал решение, но ничего не найдено (только статьи о (window:resize), но это не я ищу).

Как определить изменение размера элемента в Angular 2?

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

Я хочу использовать некоторые анимации CSS и обнаруживать элементы height и width.

Ответ 1

Проблема не проблема Angular 2. В более общем плане, как вы определяете изменения размера в любом элементе, отличном от window? Существует событие onresize, но это срабатывает только для window, и нет других очевидных решений.

Общий способ, которым многие подходят к этому, - установить интервал, скажем, 100 мс, и проверить ширину и высоту div, чтобы обнаружить изменение. Как это ни ужасно, это самый распространенный подход.

От этот ответ к более общему вопросу, есть библиотека для этого, используя только события: http://marcj.github.io/css-element-queries/. Предположительно, это неплохо. Вы бы использовали ResizeSensor, чтобы получить то, что ищете.

Если, конечно, вы ожидаете, что размер div изменится, когда появится окно. Тогда onresize - это то, что вы ищете.

Ответ 2

Обнаружение изменений в любом элементе угловой составляющей. Мы можем использовать ResizeObserver (класс из import ResizeObserver from 'resize-observer-polyfill';) без библиотеки.

вот моя реализация:

Импортировать:

import ResizeObserver from 'resize-observer-polyfill';

Реализация:

@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);
  }

Ответ 3

Два сценария должны быть обнаружены:

  1. Элемент изменен
  2. Размер окна изменен

Поскольку угловые, если часто изменяющий элемент (добавление классов и т.д.), Важно дождаться, пока изменения не будут "сделаны". Наблюдаемые могут быть использованы для этого.

ДЕМО: https://stackblitz.com/edit/angular-mutationobserver-example-tmafmw

Код JS:

import { Component ,HostListener, AfterViewInit, ViewChild, ElementRef, OnInit, OnDestroy } from '@angular/core';
import { AppService } from './app.service';
import { Subscription, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

class HeightAndWidth{
  height:number;    
  width:number;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  public elements: string[];
  public height:number = 0;
  public width:number = 0;

  constructor(private appService: AppService) {
    this.elements = ['an element', 'another element', 'who cares'];
  }

  addElement(): void {
    this.elements.push('adding another');
  }

  removeElement(index: number): void {
    this.elements.splice(index, 1);
  }

  private subscription: Subscription;
  @ViewChild('divToTrackHeightChanges') divToTrackHeightChanges:ElementRef;  

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.doDivHeightChange(this.getHeightAndWidthObject());    
  }

  getHeightAndWidthObject():HeightAndWidth{
    const newValues = new HeightAndWidth();
    newValues.height = this.divToTrackHeightChanges.nativeElement.offsetHeight;
    newValues.width = this.divToTrackHeightChanges.nativeElement.offsetWidth;
    return newValues;
  }
  setupHeightMutationObserver() {
    const observerable$ = new Observable<HeightAndWidth>(observer => {
      // Callback function to execute when mutations are observed
      // this can and will be called very often
      const callback = (mutationsList, observer2)=> {
        observer.next(this.getHeightAndWidthObject());
      };
      // Create an observer instance linked to the callback function
      const elementObserver = new MutationObserver(callback);

      // Options for the observer (which mutations to observe)
      const config = { attributes: true, childList: true, subtree: true };
      // Start observing the target node for configured mutations
      elementObserver.observe(this.divToTrackHeightChanges.nativeElement, config);      
    });

    this.subscription = observerable$
      .pipe(
        debounceTime(50),//wait until 50 milliseconds have lapsed since the observable was last sent
        distinctUntilChanged()//if the value hasn't changed, don't continue
      )
      .subscribe((newValues => {
        this.doDivHeightChange(newValues);
      }));
  }

  doDivHeightChange(newValues:HeightAndWidth){
   this.height = newValues.height;
   this.width = newValues.width;
  }

  ngAfterViewInit() {
    this.setupHeightMutationObserver();
    this.doDivHeightChange(this.getHeightAndWidthObject());
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}