iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
JavaScript

PM說: RD大大,這個功能要怎麼寫啊?系列 第 8

PM 說: 要怎麼防止用戶沒存檔手滑關閉網頁?

  • 分享至 

  • xImage
  •  

gmail

前言

封面圖是 gmail 寫信寫到一半手滑關閉網頁 彈出的提示

試想一個情境:
你正在後台編輯很長的表單,打到一半去處理其他事情,要回來繼續編輯表單
因為分頁太~~~多所以手滑點到叉叉....此時網頁就沒存檔
/images/emoticon/emoticon17.gif

今天會介紹最簡單的作法避免上述情況

網頁生命週期

首先要先簡單知道網頁分成5個階段

  1. loading (載入中)
  2. interactive == DOMContentLoaded (文件已經完成讀取。可以使用 DOM 元素)
  3. complete == load (頁面所有資源已經完成讀取。)
  4. beforeunload (離開網頁前)
  5. unload (已關閉網頁 or 已重新整理網頁)

我們要達成目標需要在 4. beforeunload 階段做事件監聽

成果

讀者們可以親自試試:網頁生命週期demo
demo

細心的讀者會發現 demo 故意將比較早印出的 EventListener 放比較後面
這樣比較能理解順序的差異

可以嘗試操作幾個流程:

  1. 開啟網頁>>不做任何事情>>關閉
  2. 開啟網頁>>滑鼠點一下>>關閉/重新整理
  3. 開啟網頁>>鍵盤按一下>>關閉/重新整理

補充幾個重點:

  1. 要彈出提示需要先跟網頁有互動過(和瀏覽器播放音效機制類似)
  2. 提示文字無法客製化,alert()也無法生效
    詳見

程式碼

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>web-life-cycle</title>
  </head>
  <body>
    <h1>網頁生命週期 dmo</h1>
    <pre>
        請開啟檢查(F12)
    </pre>

    <h3>"離開網頁監聽"注意事項</h3>
    <ol>
      <li>要先和網頁互動過一次 才會提示(事件正確綁上去) ex: 鍵盤打字, 滑鼠點擊</li>
      <li>試著關閉網頁,會跳出題示,alert內容無法更改(防詐騙政策)</li>
    </ol>
    <br />

    <p>您的網頁已重開: <span id="closeWebCounter"></span> 次</p>

    <script>
      //2-2
      window.addEventListener("load", function (event) {
        console.log("All resources finished loading!", Date.now());
      });

      //1-2
      document.addEventListener("DOMContentLoaded", function () {
        console.log("DOM ready!", Date.now());
      });

      document.addEventListener("readystatechange", (e) => {
        switch (document.readyState) {
          case "interactive":
            // 1-1
            console.log("文件已經完成讀取。可以使用 DOM 元素。", Date.now());
            break;
          case "complete":
            // 2-1
            console.log("頁面已經完成讀取。", Date.now());
            break;
        }
      });

      //3
      window.addEventListener("beforeunload", (event) => {
        //不會觸發
        alert("886");
        event.returnValue = `Are you sure you want to leave?`; //以前可以改文字,現在不行了
        return 'You have unsaved changes!';
      });

      //4
      window.addEventListener("unload", (event) => {
        const closeWebTimes = localStorage.getItem("已關閉網頁次數") || 0;
        const newValue = Number(closeWebTimes) + 1;
        localStorage.setItem("已關閉網頁次數", newValue);
      });

      //0
      console.log(document.readyState, Date.now());
      closeWebCounter.textContent = localStorage.getItem("已關閉網頁次數") || 0;
    </script>
  </body>
</html>


後記

研究後才知道原來可以在關閉網頁後做事情
至於手機不會觸發哪些事件還需要繼續研究

值得閱讀的好文章

Sure you want to leave?—browser beforeunload event

重新認識 JavaScript 番外篇 (6) - 網頁的生命週期


上一篇
PM 說: 要怎麼寫出ISBN條碼和帳單上的一維條碼?
下一篇
PM 說: 很多表格的 A4 表單 AI 能幫忙切版嗎?
系列文
PM說: RD大大,這個功能要怎麼寫啊?20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言