Angular 監聽瀏覽器事件(刷新/關閉/...)

在項目中,關于Angular路由跳轉的控制(Guard)如果基本都是基于CanActivateecanDeactivate,我在文章Angular的守門員canActivate與canDeactivate有較為詳細的介紹,但是最后也提到,對于瀏覽器的刷新和關閉,canDeactivate并不能處理,所以還是得回歸本質,直接監聽瀏覽器事件。

一,可監聽的事件的列表

學過御三家 Html , css, js 的人應該有耳聞W3School,這個強大的網站同樣也列出了

我們在開發過程中可能需要監聽的事件列表([鏈接][https://www.w3school.com.cn/tags/html_ref_eventattributes.asp])。

本文的目的是監聽瀏覽器事件,但因為瀏覽器的刷新和關閉會直接觸發Window事件,所以實際上我們監聽的是Html中的Window事件。這里就只簡單列出比較常用的幾個事件:

事件名稱 屬性(window.x) 觸發時機
beforeunload onbeforeunload 顧名思義,當用戶卸載文檔執行之前觸發
unload onunload 當用戶卸載文檔執行時觸發(瀏覽器關閉)
load onload 頁面加載之后立即觸發
resize onresize 當瀏覽器窗口被調整大小時觸發

一些使用場景:

  • unload: 可以類比 onDestroy(),我們可以在里面寫一些清空臨時數據之類的操作;
  • load:可以類比onInit(),可以執行一些初始化的函數在里面;
  • resize:可以直接想到的就是界面大小變化后界面動態適配;
  • beforeunload:這個可以想像成 before ngOnDestroy(),就是還沒Destroy之前的操作,這也是經常用到一個事件。

二,@HostListener

我們在上面我的一篇文章寫到一個場景,就是用戶在編輯還未保存的情況下離開當前界面,我們需要給他個提醒,當時我們用canDeactivate已經解決了大部分場景,但是針對瀏覽器刷新和關閉不能處理,所以來看看Angular中的 Dom Event Listner@HostListener

官方的解釋是:

Decorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs.

大致意思:

  1. 它是個修飾器(一看帶了個@);
  2. 它需要你傳入兩個參數:
    • eventName: string // 監聽的事件名稱
    • args: string[] // 事件發生時傳給處理器的參數

注意,我們要傳的是事件名稱,不是屬性,比如你要監聽unload,就應該寫:

@HostListener('window:unload', [`$event`]) ...  // right !
@HostListener('window.onunload', [`$event`]) ...  // wrong !
@HostListener('window:onunload', [`$event`]) ...  // wrong !

三,實例

還是那個場景,未保存修改刷新/關閉瀏覽器,彈出提示:

import { 
    ...
    HostListener,
    ...
} from '@angular/core';

...
@HostListener('window:beforeunload', ['$event'])
private beforeUnload(event: Event) {
  if(this.form.dirty) {
    event.preventDefault();
    event.returnValue = true;  // Chrome requires returnValue to be set.
  }
}
....

來看一下代碼,我已經標注了非常重要的一步,我們必須對該 event-unload來返回一個值,以此來暫停事件的繼續進行(become unload)來達到我們所預期的目的。

如果不寫這一句,直接寫你的代碼邏輯:

...
private beforeUnload(event: Event) {
  if(this.form.dirty) {
    // event.preventDefault();
    // event.returnValue = true;
    return this.alertService.alert('Are you confrimed ?');
  }
}
...

像這樣的話,你會發現你的代碼確實是執行了,但是頁面同樣繼續執行了刷新,與我們的期望背道而馳。

提示

這個before unload事件我們寫的 returnValue = true實際上你可以寫any thing,因為他都會彈出一個基于瀏覽器的提示框,這個東西就不受你的ux掌控了,所以如果選擇使用,請首先和你的ux確定,他/她覺得可以這樣做,不然別好心卻被罵了。

以上本文完結。由錯誤的地方或者需要討論的地方請多多指正。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • ??JavaScript 與 HTML 之間的交互是通過事件實現的。 ??事件,就是文檔或瀏覽器窗口中發生的一些特...
    霜天曉閱讀 3,528評論 1 11
  • 本節介紹各種常見的瀏覽器事件。 鼠標事件 鼠標事件指與鼠標相關的事件,主要有以下一些。 click 事件,dblc...
    許先生__閱讀 2,494評論 0 4
  • 之前寫過一篇瀏覽器事件的相關操作和事件運行的原理——JavaScript瀏覽器事件解析。這一篇主要寫一些常用的事件...
    faremax閱讀 1,653評論 0 0
  • 資源事件 beforeunload 事件 beforeunload事件在窗口、文檔、各種資源將要卸載前觸發。它可以...
    oWSQo閱讀 633評論 0 1
  • JavaScript 與 HTML 之間的交互是通過事件實現的。事件,就是文檔或瀏覽器窗口中發生的一些特定的交互瞬...
    LemonnYan閱讀 698評論 0 4