ウィンドウサイズ変更イベント(負荷時および動的)に基づいていくつかのタスクを実行したいと思います。
現在私は次のように私のDOMを持っています:
<div id="Harbour">
<div id="Port" (window:resize)="onResize($event)" >
<router-outlet></router-outlet>
</div>
</div>
イベントは正しく発生します
export class AppComponent {
onResize(event) {
console.log(event);
}
}
このイベントオブジェクトから幅と高さを取得する方法を教えてください。
ありがとう。
<div (window:resize)="onResize($event)"
onResize(event) {
event.target.innerWidth;
}
または
@HostListener('window:resize', ['$event'])
onResize(event) {
event.target.innerWidth;
}
サポートされているグローバルターゲットはwindow
、document
、およびbody
です。
https://github.com/angular/angular /issues/3248 がAngularに実装されるまでは、DOMイベントへのサブスクライブを必須とし、RXJSを使用してイベント数を削減するのがパフォーマンス上優れています。他の答えのいくつかに見られるように。
@ギュンターの答えは正しいです。私はまだ別の方法を提案したいと思いました。
@Component()
-デコレータの中にHost-bindingを追加することもできます。次のように、イベントと必要な関数呼び出しをHost-metadata-propertyに入れることができます。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
Host: {
'(window:resize)': 'onResize($event)'
}
})
export class AppComponent{
onResize(event){
event.target.innerWidth; // window width
}
}
これを行う正しい方法は、 EventManager クラスを使用してイベントをバインドすることです。これにより、コードを別のプラットフォーム、たとえばAngular Universalを使用したサーバーサイドレンダリングで機能させることができます。
import { EventManager } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Injectable } from '@angular/core';
@Injectable()
export class ResizeService {
get onResize$(): Observable<Window> {
return this.resizeSubject.asObservable();
}
private resizeSubject: Subject<Window>;
constructor(private eventManager: EventManager) {
this.resizeSubject = new Subject();
this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
}
private onResize(event: UIEvent) {
this.resizeSubject.next(<Window>event.target);
}
}
コンポーネントでの使用方法は、このサービスをプロバイダとしてapp.moduleに追加してからコンポーネントのコンストラクタにインポートするだけです。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
template: ``,
styles: [``]
})
export class MyComponent implements OnInit {
private resizeSubscription: Subscription;
constructor(private resizeService: ResizeService) { }
ngOnInit() {
this.resizeSubscription = this.resizeService.onResize$
.subscribe(size => console.log(size));
}
ngOnDestroy() {
if (this.resizeSubscription) {
this.resizeSubscription.unsubscribe();
}
}
}
これを実行するためのより良い方法です。 Birowskyの answerに基づく。
ステップ1:RxJS Observables でangular service
を作成します。
import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
@Injectable()
export class WindowService {
height$: Observable<number>;
//create more Observables as and when needed for various properties
hello: string = "Hello";
constructor() {
let windowSize$ = new BehaviorSubject(getWindowSize());
this.height$ = (windowSize$.pluck('height') as Observable<number>).distinctUntilChanged();
Observable.fromEvent(window, 'resize')
.map(getWindowSize)
.subscribe(windowSize$);
}
}
function getWindowSize() {
return {
height: window.innerHeight
//you can sense other parameters here
};
};
ステップ2:上記のservice
を挿入して、ウィンドウサイズ変更イベントを受信したい場所で、サービス内で作成された任意のObservables
を購読します。
import { Component } from '@angular/core';
//import service
import { WindowService } from '../Services/window.service';
@Component({
selector: 'pm-app',
templateUrl: './componentTemplates/app.component.html',
providers: [WindowService]
})
export class AppComponent {
constructor(private windowService: WindowService) {
//subscribe to the window resize event
windowService.height$.subscribe((value:any) => {
//Do whatever you want with the value.
//You can also subscribe to other observables of the service
});
}
}
リアクティブプログラミングを正しく理解することは、常に困難な問題を克服するのに役立ちます。これが誰かに役立つことを願っています。
私はこれがずっと前に頼まれたことを知っています、しかし今これをするためのより良い方法があります!だれかがこの答えを見るかどうか私にはわかりません。明らかにあなたの輸入品:
import { fromEvent } from "rxjs/observable/fromEvent";
import { Observable } from "rxjs/Observable";
import { Subscription } from "rxjs/Subscription";
それからあなたのコンポーネントで:
resizeObservable$: Observable<Event>
resizeSubscription$: Subscription
ngOnInit() {
this.resizeObservable$ = fromEvent(window, 'resize')
this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => {
console.log('event: ', evt)
})
}
それから、破棄の登録を解除してください!
ngOnDestroy() {
this.resizeSubscription$.unsubscribe()
}
誰もがangular/cdk
のMediaMatcher
について話しているのを見たことがありません。
MediaQueryを定義してそれにリスナーをアタッチすることができます - そしてテンプレート(またはts)のどこでもMatcherがマッチすればものを呼び出すことができます。 LiveExample
App.Component.ts
import {Component, ChangeDetectorRef} from '@angular/core';
import {MediaMatcher} from '@angular/cdk/layout';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mobileQuery: MediaQueryList;
constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) {
this.mobileQuery = media.matchMedia('(max-width: 600px)');
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this._mobileQueryListener);
}
private _mobileQueryListener: () => void;
ngOnDestroy() {
this.mobileQuery.removeListener(this._mobileQueryListener);
}
}
App.Component.Html
<div [class]="mobileQuery.matches ? 'text-red' : 'text-blue'"> I turn red on mobile mode
</div>
App.Component.css
.text-red {
color: red;
}
.text-blue {
color: blue;
}
ソース: https://material.angular.io/components/sidenav/overview
<600pxがあなたにとってモバイルであることを意味すると仮定すると、このオブザーバブルを使用してそれを購読することができます。
まず、現在のウィンドウサイズが必要です。そのため、単一の値(現在のウィンドウサイズ)のみを出力する観測量を作成します。
initial$ = Observable.of(window.innerWidth > 599 ? false : true);
それから、ウィンドウサイズがいつ変更されたかがわかるように、別の観測量を作成する必要があります。これには "fromEvent"演算子を使うことができます。 rxjsの演算子の詳細については、次のURLをご覧ください。 rxjs
resize$ = Observable.fromEvent(window, 'resize').map((event: any) => {
return event.target.innerWidth > 599 ? false : true;
});
これら2つのストリームをマージして、観測量を取得します。
mobile$ = Observable.merge(this.resize$, this.initial$).distinctUntilChanged();
今、あなたはこのようにそれを購読することができます:
mobile$.subscribe((event) => { console.log(event); });
退会することを忘れないでください:)
@cgatianの解決法に基づいて、次の単純化を提案します。
import { EventManager } from '@angular/platform-browser';
import { Injectable, EventEmitter } from '@angular/core';
@Injectable()
export class ResizeService {
public onResize$ = new EventEmitter<{ width: number; height: number; }>();
constructor(eventManager: EventManager) {
eventManager.addGlobalEventListener('window', 'resize',
e => this.onResize$.emit({
width: e.target.innerWidth,
height: e.target.innerHeight
}));
}
}
使用法:
import { Component } from '@angular/core';
import { ResizeService } from './resize-service';
@Component({
selector: 'my-component',
template: `{{ rs.onResize$ | async | json }}`
})
export class MyComponent {
constructor(private rs: ResizeService) { }
}
これは質問に対する正確な答えではありませんが、あらゆる要素のサイズの変化を検出する必要がある人に役立ちます。
resized
イベントを任意の要素に追加するライブラリを作成しました - Angular Resize Event。
内部的には CSS Element Queries からのResizeSensor
を使用しています。
<div (resized)="onResized($event)"></div>
@Component({...})
class MyComponent {
width: number;
height: number;
onResized(event: ResizedEvent): void {
this.width = event.newWidth;
this.height = event.newHeight;
}
}
このlib はAngularでコンポーネントの境界サイズの変更(サイズ変更)を行ったことを見つけるために書きました。これは他の人々に役立つかもしれません。あなたはそれをルートコンポーネントに置くかもしれません、ウィンドウサイズ変更と同じことをするでしょう。
ステップ1: モジュールをインポートする
import { BoundSensorModule } from 'angular-bound-sensor';
@NgModule({
(...)
imports: [
BoundSensorModule,
],
})
export class AppModule { }
ステップ2: 以下のようにディレクティブを追加する
<simple-component boundSensor></simple-component>
ステップ3: 境界サイズの詳細を受け取る
import { HostListener } from '@angular/core';
@Component({
selector: 'simple-component'
(...)
})
class SimpleComponent {
@HostListener('resize', ['$event'])
onResize(event) {
console.log(event.detail);
}
}
On Angular 2(2.1.0)ngZoneを使って画面変更イベントをキャプチャしました。
例を見てください。
import { Component, NgZone } from '@angular/core';//import ngZone library
...
//capture screen changed inside constructor
constructor(private ngZone: NgZone) {
window.onresize = (e) =>
{
ngZone.run(() => {
console.log(window.innerWidth);
console.log(window.innerHeight);
});
};
}
私はこれが助けを願っています!
angular CDKには ViewportRuler サービスがあります。ゾーンの外側で実行され、サーバー側のレンダリングでも動作します。
以下のコードはAngularで与えられたdivのサイズ変更を観察することを可能にします。
<div #observed-div>
</div>
それからコンポーネントの中で:
oldWidth = 0;
oldHeight = 0;
@ViewChild('observed-div') myDiv: ElementRef;
ngAfterViewChecked() {
const newWidth = this.myDiv.nativeElement.offsetWidth;
const newHeight = this.myDiv.nativeElement.offsetHeight;
if (this.oldWidth !== newWidth || this.oldHeight !== newHeight)
console.log('resized!');
this.oldWidth = newWidth;
this.oldHeight = newHeight;
}