🐟

[Angular] ブラウザを閉じる・リロードのタイミングで処理を実行する @HostListener

2022/12/13に公開

Angularアプリを終了するときに処理を実行したい

AngularにはngOnDestroyというライフサイクルメソッドがありますが、これはブラウザのタブがリロードされたり、ブラウザを閉じたりURLが新しいページに変更されたりするときには、このフックは実行されません。

Angularアプリ全体が破壊されたとき、何らかの処理を挟みたい時はどうすればよいでしょうか?

💡 結論、@HostListenerとWindow: beforeunloadまたはunloadを使う。

@HostListenerデコレータとは

ディレクティブに対してイベントハンドラーを紐づけることができます。
ディレクティブ以外にも、windowイベント(unloadなど)のイベントにも紐づけることができます。
任意のイベントハンドラの前にHostListenerデコレータを付けます。

@HostListener(name [,args]) 関数() { 処理 };
  • name : イベント名
  • args : イベントハンドラーに渡す引数

使い所

💡 window/documentイベントを捕捉するときに使う

Angularにおいて、ある操作に対してイベントを紐づけるのは簡単にできます。

例) クリックイベント ボタンをクリックするとcounterがプラス1される、

<button (click)="increment()">プラス1</button>
------------------------------------------------
counter = 0;

increment() {
  this.counter++;
}

しかし、ボタンなどの特定の要素に対してではなく、それ以外の要素に対してイベントを紐づけたいときはどうでしょう?

例えば、どこでもいいのでエンターキーを押すとプラス1するなど。
そんな時に使えるのが、この@HostListenerデコレータです。
これを使うと、指定したイベントを常にリッスンしてくれます。

次の例はウィンドウ上でEnterキーを押したときに、イベントをリッスンする別のイベントハンドラを登録しています。

<h1>あなたは、 {{ counter }} 回エンターキーを押しました。</h1>
<button (click)="resetCounter()">リセット</button>
import { Component, HostListener, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular ' + VERSION.major;

  counter = 0;

  @HostListener('window:keydown.enter', ['$event'])
  handlekeyDown(event: KeyboardEvent) {
    this.counter++;
  }
  resetCounter() {
    this.counter = 0;
  }
}

イベント例

イベント 内容
@HostListener( ‘document:click’, [ ‘$event’ ] ) ブラウザのどこかをクリック時
@HostListener( ‘document:mouseover’, [ ‘$event’ ] ) ブラウザにマウスオーバー時
@HostListener( ‘window:resize’, [ ‘$event’ ] ) ブラウザのリサイズ時

unloadやbeforeunloadを使う

さて、@HostLisnerの使い方が分かったところで、ブラウザが閉じるタイミングで処理を実行する処理を実装していきます。
unloadbeforeunloadという2つのDOMイベントに対して@HostListenerでリッスンしてあげればOKです。

export class AppComponent implements OnInit {
  @HostListener(window:unload’, [ ‘$event’ ])
  unloadHandler(event) {
    // 処理
  }
  @HostListener(window:beforeunload’, [ ‘$event’ ])
   beforeUnloadHandler(event) {
     // 処理
   }
}
  • unload: 更新後のページで実行
  • beforeunload : 更新前のページで実行

注意

Window: beforeunloadやunloadイベントの実行中は、window.alert(), window.confirm(), window.prompt()メソッドは無視されてしまいます。

参考

https://qiita.com/zyufu_0tuka/items/3017c5bf82c8c9145fa7
https://medium.com/ngconf/run-code-when-you-leave-your-angular-app-d4ef30472d20
https://pisuke-code.com/js-how-to-detect-browser-unload/
https://angular.jp/api/core/HostListener

https://blog.officekoma.co.jp/2018/08/windowdocumentangularhostlistener.html

Discussion