检测角度4的实时窗口大小变化

我一直在尝试建立一个响应导航条,不希望使用媒体查询,所以我打算使用 *ngIf与窗口大小作为一个标准。 但我一直面临着一个问题,因为我无法找到任何方法或文件的角度4窗口大小检测。我也尝试了 JavaScript 方法,但它不受支持。

我也试过 跟随:

constructor(platform: Platform) {
platform.ready().then((readySource) => {
console.log('Width: ' + platform.width());
console.log('Height: ' + platform.height());
});
}

用于离子。

还有 screen.availHeight但还是没有成功。

224911 次浏览

你可以用这个 Https://github.com/manucutillas/ng2-responsive 希望对你有所帮助: -)

把它放进去

public innerWidth: any;
ngOnInit() {
this.innerWidth = window.innerWidth;
}

如果你想更新它的大小:

@HostListener('window:resize', ['$event'])
onResize(event) {
this.innerWidth = window.innerWidth;
}

Platform width()height()的文档中,说明了这些方法分别使用 window.innerWidthwindow.innerHeight。但是使用这些方法更好,因为维度是缓存的值,这减少了多次昂贵的 DOM 读取的机会。

import { Platform } from 'ionic-angular';


...
private width:number;
private height:number;


constructor(private platform: Platform){
platform.ready().then(() => {
this.width = platform.width();
this.height = platform.height();
});
}

如果你希望你的组件保持容易测试,你应该把全局窗口对象包装成一个角度服务:

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


@Injectable()
export class WindowService {


get windowRef() {
return window;
}


}

然后,您可以像注入其他服务一样:

constructor(
private windowService: WindowService
) { }

消耗..。

  ngOnInit() {
const width= this.windowService.windowRef.innerWidth;
}

如果你想对某些断点做出反应(例如,如果宽度是768px 或更小) ,你可以使用 BreakpointObserver:

import { Component } from '@angular/core';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';


@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {


constructor(
private breakpointObserver: BreakpointObserver,
) {
// detect screen size changes
this.breakpointObserver.observe([
"(max-width: 768px)"
]).subscribe((result: BreakpointState) => {
if (result.matches) {
// hide stuff
} else {
// show stuff
}
});
}
}
@HostListener("window:resize", [])
public onResize() {
this.detectScreenSize();
}


public ngAfterViewInit() {
this.detectScreenSize();
}


private detectScreenSize() {
const height = window.innerHeight;
const width = window.innerWidth;
}

这是我使用的服务的一个例子。

您可以通过订阅 screenWidth$或通过 screenWidth$.value获得屏幕宽度。

mediaBreakpoint$(或 mediaBreakpoint$.value)也是如此

import {
Injectable,
OnDestroy,
} from '@angular/core';
import {
Subject,
BehaviorSubject,
fromEvent,
} from 'rxjs';
import {
takeUntil,
debounceTime,
} from 'rxjs/operators';


@Injectable()
export class ResponsiveService implements OnDestroy {
private _unsubscriber$: Subject<any> = new Subject();
public screenWidth$: BehaviorSubject<number> = new BehaviorSubject(null);
public mediaBreakpoint$: BehaviorSubject<string> = new BehaviorSubject(null);


constructor() {
this.init();
}


init() {
this._setScreenWidth(window.innerWidth);
this._setMediaBreakpoint(window.innerWidth);
fromEvent(window, 'resize')
.pipe(
debounceTime(1000),
takeUntil(this._unsubscriber$)
).subscribe((evt: any) => {
this._setScreenWidth(evt.target.innerWidth);
this._setMediaBreakpoint(evt.target.innerWidth);
});
}


ngOnDestroy() {
this._unsubscriber$.next();
this._unsubscriber$.complete();
}


private _setScreenWidth(width: number): void {
this.screenWidth$.next(width);
}


private _setMediaBreakpoint(width: number): void {
if (width < 576) {
this.mediaBreakpoint$.next('xs');
} else if (width >= 576 && width < 768) {
this.mediaBreakpoint$.next('sm');
} else if (width >= 768 && width < 992) {
this.mediaBreakpoint$.next('md');
} else if (width >= 992 && width < 1200) {
this.mediaBreakpoint$.next('lg');
} else if (width >= 1200 && width < 1600) {
this.mediaBreakpoint$.next('xl');
} else {
this.mediaBreakpoint$.next('xxl');
}
}


}


希望这对谁有帮助

答案很简单,写下下面的代码

import { Component, OnInit, OnDestroy, Input } from "@angular/core";
// Import this, and write at the top of your .ts file
import { HostListener } from "@angular/core";


@Component({
selector: "app-login",
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})


export class LoginComponent implements OnInit, OnDestroy {
// Declare height and width variables
scrHeight:any;
scrWidth:any;


@HostListener('window:resize', ['$event'])
getScreenSize(event?) {
this.scrHeight = window.innerHeight;
this.scrWidth = window.innerWidth;
console.log(this.scrHeight, this.scrWidth);
}


// Constructor
constructor() {
this.getScreenSize();
}
}

您可以为这个场景使用 typecript getter 方法

public get width() {
return window.innerWidth;
}

在模板中使用如下:

<section [ngClass]="{ 'desktop-view': width >= 768, 'mobile-view': width < 768
}"></section>

您不需要任何事件处理程序来检查窗口的大小调整,此方法将每次自动检查大小。

现在我知道这个问题最初是指 屏幕尺寸,所以基本上是 widthheight属性,但是对于大多数人来说,Breakpoints才是真正重要的,因此,为了使一个全局可重用的解决方案,我更喜欢使用 AngularBreakpointObserver来处理这个问题。

下面的配置基本上是一个 service和一些 functions,可以 returnObservable<BreakpointState>subscribed在任何需要的地方:

import { Injectable } from '@angular/core';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { Observable } from 'rxjs';


@Injectable({
providedIn: 'root',
})
export class ScreenService {


constructor(private observer: BreakpointObserver) {}


isBelowSm(): Observable<BreakpointState> {
return this.observer.observe(['(max-width: 575px)']);
}


isBelowMd(): Observable<BreakpointState> {
return this.observer.observe(['(max-width: 767px)']);
}


isBelowLg(): Observable<BreakpointState> {
return this.observer.observe(['(max-width: 991px)']);
}


isBelowXl(): Observable<BreakpointState> {
return this.observer.observe(['(max-width: 1199px)']);
}
}

以上代码可以通过调整 bootstrap处理屏幕大小的方式(通过将 ABC1改为 ABC2,并为每个值增加 ABC3,当然还要逆转 function的名称。)

现在在 component class中,通过上述任何函数返回的 subscribingobservable就可以了。

即: app.component.ts :

export class AppComponent implements AfterViewInit {


isBelowLg: boolean;


constructor(private screenService: ScreenService) {}


ngAfterViewInit(): void {
this.screenService.isBelowLg().subscribe((isBelowLg: BreakpointState) => {
this.isBelowLg = isBelowLg.matches;
});
}
}

参考使用 AfterViewInit生命周期钩子将节省大量的麻烦,当它来到 detectChanges()后,视图初始化。

编辑:

作为 AfterViewInit的替代方案,它是相同的,但是另外,您需要使用 ChangeDetectorRefdetectChanges(),只需在订阅组件 即: app.component.ts中注入一个实例,如下所示:

constructor(
private screenService: ScreenService,
private cdref: ChangeDetectorRef
) {}

之后,只要打个电话给 detectChanges()就可以了:

this.cdref.detectChanges();