因為會忘,所以要寫下來

Angular Window Resize Event (偵測視窗縮放事件)

3 minutes to read

偶然發現 Angular 有蠻多種方式可以偵到一些視窗事件,順手記錄下來

template 傳送事件

<div (window:resize)="onResize($event)"></div>
onResize(event: Event) {
  event.target.innerWidth;
}

HostListener

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

Component host

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  host: {
    '(window:resize)': 'onResize($event)',
  },
})

onResize(event: Event) {
  event.target.innerWidth;
}

RxJS

@Component({
  ...
})
export class AppComponent implements OnInit, OnDestroy {
  resizeObservable$: Observable<Event> = fromEvent(window, 'resize');
  resizeSubscription$!: Subscription;

  ngOnInit(): void {
     this.resizeSubscription$ = this.resizeObservable$.subscribe((e) => {
      // do Something
    });
  }

  // 離開後解訂閱
  ngOnDestroy() {
    this.resizeSubscription$.unsubscribe();
  }
}

subscribe 前 可再多做些設定,當 resize 時,不用一直觸發,300ms 偵測一次就好

this.resizeSubscription$ = this.resizeObservable$
  .pipe(debounceTime(300))
  .subscribe((e) => {
    // do Something
  });

如何一開始就偵側到視窗大小

@Component({
  selector: "app-about",
  templateUrl: "./about.component.html",
  styleUrls: ["./about.component.scss"],
})
export class AboutComponent implements OnInit, OnDestroy {
  // 初始化
  initial$ = of(window).pipe(
    map((event: any) => {
      return {
        width: event.innerWidth,
        height: event.innerHeight,
      }
    })
  )
  // 當視窗拖動的時後
  resize$ = fromEvent(window, "resize").pipe(
    map((event: Event) => {
      return {
        width: event.target.innerWidth,
        height: event.target.innerHeight,
      }
    })
  );
  winSize$ = merge(this.resize$, this.initial$).pipe(distinctUntilChanged());
  subscription$!: Subscription;
  constructor() {}

  ngOnInit(): void {
    this.subscription$ = this.winSize$.subscribe({ width, height} => {
      console.log('width', width, 'height', height);
    });
  }

  ngOnDestroy() {
    // 記得解訂閱
    this.subscription$.unsubscribe();
  }
}

對這篇文章有什麼想法嗎?

Copyright © 2024 Mandy. All rights reserved. Build with Astro