我正在寻找一个解决方案,但没有找到(只有文章(window:resize),但我不是在寻找).
如何检测元素大小的变化Angular 2?
<div #myElement (sizeChanged)="callback()" />
Run Code Online (Sandbox Code Playgroud)
我想使用一些CSS动画并检测元素height和width变化.
Cob*_*ger 16
问题甚至不是Angular 2问题.更一般地说,如何检测除了window?之外的任何元素的大小变化?有一个onresize事件,但这只是触发,window并没有其他明显的解决方案.
许多人接近这一点的一般方法是设置一个间隔,例如100毫秒,并检查div的宽度和高度以检测变化.虽然听起来很可怕,但这是最常见的方法.
从这个答案到更一般的问题,有一个库只使用事件来做到这一点:http://marcj.github.io/css-element-queries/.据说,它非常好.你会用它ResizeSensor来得到你想要的东西.
除非当然,你只是期望div在窗口时调整大小.那onresize就是你要找的东西.
检测角度分量的任何元素的变化。我们可以使用不带库的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 经常修改元素(添加类等),因此等待更改“完成”非常重要。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)
对于有角的用户,您可以轻松地应用此代码....
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