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

时间:2016-11-17 15:41:11

标签: angular

我一直在寻找解决方案,但没有找到(只有关于(window:resize)的文章,但它不是我想要的。)

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

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

我想使用一些CSS动画并检测元素的heightwidth更改。

5 个答案:

答案 0 :(得分:15)

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

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

this answer到更一般的问题,有一个库只使用事件来执行此操作:http://marcj.github.io/css-element-queries/。据说,它非常好。您可以使用ResizeSensor来获取您正在寻找的内容。

除非当然,您只希望div在窗口时调整大小。然后onresize就是你要找的东西。

答案 1 :(得分:3)

检测角度分量中任何元素的变化。我们可以使用 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);
  }

答案 2 :(得分:3)

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

HTML

<div (resized)="onResized($event)"></div>

角度

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

请记住,您必须安装节点模块并将其导入到 app.module.ts 文件中。

检查此链接以获取更多信息: https://www.npmjs.com/package/angular-resize-event

答案 3 :(得分:0)

必须检测到两种情况:

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

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>

答案 4 :(得分:-1)

一个非常优雅的解决方案,类似于使用RxJS的最佳答案...

HTML

library(dplyr)
library(tidyr)
df1 %>% 
  pivot_longer(cols = everything(), names_to = c(".value", "group"),
        names_sep="(?<=[a-z])(?=\\d+)") %>%
  group_by(group, Car) %>% 
  summarise(Mean = mean(Time), SD = sd(Time))
# A tibble: 7 x 4
# Groups:   group [3]
#  group   Car  Mean    SD
#  <chr> <int> <dbl> <dbl>
#1 1        11  10     0  
#2 1        22  40    20  
#3 2        33  50    56.6
#4 2        45  30.5  33.3
#5 3        40  25    21.2
#6 3        88  45    21.2
#7 3        90  60    56.6

组件或指令

<element-to-watch #ref></element-to-watch>