我一直在尝试构建一个响应式导航栏,并且不希望使用媒体查询,所以我打算使用*ngIF窗口大小作为标准.但我一直面临一个问题,因为我无法找到任何关于Angular 4窗口大小检测的方法或文档.我也尝试过JavaScript方法,但不支持.
我也尝试过以下方法:
constructor(platform: Platform) {
platform.ready().then((readySource) => {
console.log('Width: ' + platform.width());
console.log('Height: ' + platform.height());
});
}
Run Code Online (Sandbox Code Playgroud)
...用于离子.
并且screen.availHeight,但仍然没有成功.
Edu*_*gas 183
在init上获取它
public innerWidth: any;
ngOnInit() {
this.innerWidth = window.innerWidth;
}
Run Code Online (Sandbox Code Playgroud)
如果你想在调整大小时保持更新:
@HostListener('window:resize', ['$event'])
onResize(event) {
this.innerWidth = window.innerWidth;
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*nks 20
如果您想对某些断点做出反应(例如,如果宽度小于768px则执行某些操作),您还可以使用BreakpointObserver:
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
{ ... }
const isSmallScreen = breakpointObserver.isMatched('(max-width: 599px)');
Run Code Online (Sandbox Code Playgroud)
甚至听取对该断点的更改:
breakpointObserver.observe([
'(max-width: 768px)'
]).subscribe(result => {
if (result.matches) {
doSomething();
} else {
// if necessary:
doSomethingElse();
}
});
Run Code Online (Sandbox Code Playgroud)
小智 12
这是我使用的服务示例。
您可以通过订阅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');
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于某人
对于这种情况,您可以使用 typescript getter 方法。像这样
public get width() {
return window.innerWidth;
}
Run Code Online (Sandbox Code Playgroud)
并在模板中使用它,如下所示:
<section [ngClass]="{ 'desktop-view': width >= 768, 'mobile-view': width < 768
}"></section>
Run Code Online (Sandbox Code Playgroud)
您不需要任何事件处理程序来检查窗口的大小调整,此方法将每次自动检查大小。
文件Platform width()和height(),并说明这些方法分别使用window.innerWidth和window.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();
});
}
Run Code Online (Sandbox Code Playgroud)
答案很简单。编写下面的代码
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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我知道问题最初是指屏幕尺寸,所以基本上是width和height属性,但对于大多数人来说,Breakpoints真正重要的是,因此,为了制定一个全局可重用的解决方案,我更喜欢使用来处理这个Angular问题BreakpointObserver。
以下配置基本上是可以service在任何需要的地方进行的:functionsreturnObservable<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)']);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码可以调整以处理屏幕尺寸的bootstrap方式(通过更改max-width为min-width并添加1px每个值,当然还有反转function名称。)
现在在 中component class,只需subscribing返回observable上述任何函数即可。
IE: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;
});
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在视图初始化后,使用AfterViewInit生命周期钩子会省去很多麻烦。detectChanges()
作为替代方案,AfterViewInit它是相同的,但此外,您需要使用ChangeDetectorRefto detectChanges(),只需在订阅组件中注入一个实例即可:app.component.ts如下所示:
constructor(
private screenService: ScreenService,
private cdref: ChangeDetectorRef
) {}
Run Code Online (Sandbox Code Playgroud)
之后,只需调用detectChanges()即可:
this.cdref.detectChanges();
Run Code Online (Sandbox Code Playgroud)
@HostListener("window:resize", [])
public onResize() {
this.detectScreenSize();
}
public ngAfterViewInit() {
this.detectScreenSize();
}
private detectScreenSize() {
const height = window.innerHeight;
const width = window.innerWidth;
}
Run Code Online (Sandbox Code Playgroud)
如果希望组件易于测试,则应将全局窗口对象包装在Angular Service中:
import { Injectable } from '@angular/core';
@Injectable()
export class WindowService {
get windowRef() {
return window;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以像其他任何服务一样注入它:
constructor(
private windowService: WindowService
) { }
Run Code Online (Sandbox Code Playgroud)
消耗...
ngOnInit() {
const width= this.windowService.windowRef.innerWidth;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76273 次 |
| 最近记录: |