Angular 2中的元素高度和宽度变化检测

Nic*_*kon 22 angular

我正在寻找一个解决方案,但没有找到(只有文章(window:resize),但我不是在寻找).

如何检测元素大小的变化Angular 2

<div #myElement (sizeChanged)="callback()" />
Run Code Online (Sandbox Code Playgroud)

我想使用一些CSS动画并检测元素heightwidth变化.

Cob*_*ger 16

问题甚至不是Angular 2问题.更一般地说,如何检测除了window?之外的任何元素的大小变化?有一个onresize事件,但这只是触发,window并没有其他明显的解决方案.

许多人接近这一点的一般方法是设置一个间隔,例如100毫秒,并检查div的宽度和高度以检测变化.虽然听起来很可怕,但这是最常见的方法.

这个答案到更一般的问题,有一个库只使用事件来做到这一点:http://marcj.github.io/css-element-queries/.据说,它非常好.你会用它ResizeSensor来得到你想要的东西.

除非当然,你只是期望div在窗口时调整大小.那onresize就是你要找的东西.


Suf*_*ari 7

检测角度分量的任何元素的变化。我们可以使用不带库ResizeObserver (来自的类import ResizeObserver from 'resize-observer-polyfill';)。

这是我的实现:

进口:

import ResizeObserver from 'resize-observer-polyfill';
Run Code Online (Sandbox Code Playgroud)

实现方式:

@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);
  }
Run Code Online (Sandbox Code Playgroud)

  • 如果您观察自定义 Angular 元素(例如:组件的宿主元素),请不要忘记向其添加“display: block”样式。因为它默认是“内联”的,并且没有正确的宽度/高度值。 (4认同)

bud*_*mus 6

必须检测两种情况:

  1. 元素被修改
  2. 窗口大小已调整

由于 Angular 经常修改元素(添加类等),因此等待更改“完成”非常重要。Observables 可以用于此目的。

演示: 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

HTML 代码

<div #divToTrackHeightChanges>
    <h1>Here is a div that changes</h1>    
    <span style="width:200px;display:inline-block;" *ngFor="let element of elements; let i = index">
      Element <button (click)="removeElement(i)">Remove</button>
    </span>
    <br/>
    <br/>  
  <button (click)="addElement()">Click me enough times to increase the divs height!</button>
</div>
<div>The div above has a height of  {{height}} and width of {{width}}</div>
<div>RESIZE the window to test as well</div>
Run Code Online (Sandbox Code Playgroud)


nip*_*hka 6

对于有角的用户,您可以轻松地应用此代码....

html

<div (resized)="onResized($event)"></div>
Run Code Online (Sandbox Code Playgroud)

import { Component } from '@angular/core';

// Import the resized event model
import { ResizedEvent } from 'angular-resize-event';

@Component({...})
class MyComponent {
  width: number;
  height: number;

  onResized(event: ResizedEvent) {
    this.width = event.newWidth;
    this.height = event.newHeight;
  }
}
Run Code Online (Sandbox Code Playgroud)

请记住,您必须安装node 模块并将其导入您的app.module.ts文件。

查看此链接了解更多信息: https : //www.npmjs.com/package/angular-resize-event