我一直在寻找解决方案,但没有找到(只有关于(window:resize)
的文章,但它不是我想要的。)
如何检测Angular 2
中的元素大小变化?
<div #myElement (sizeChanged)="callback()" />
我想使用一些CSS
动画并检测元素的height
和width
更改。
答案 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)
必须检测到两种情况:
由于角度较大,因此经常修改元素(添加类等),因此重要的是要等到更改“完成”。观测值可用于此目的。
演示: 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>