將迷你應用程式程式設計原則套用至範例專案

應用程式網域

為了展示適用於網頁應用程式的迷你應用程式程式設計,我需要一個小但完整的應用程式構想。高強度間歇訓練 (HIIT) 是一種心血管運動策略,會交替進行短時間的高強度有氧運動,且恢復期較少。許多 HIIT 訓練都會使用 HIIT 計時器,例如 The Body Coach TV YouTube 頻道提供的這個 30 分鐘線上課程

線上 HIIT 訓練課程,畫面上有綠色高強度計時器。
有效期。
線上高強度間歇訓練線上課程,紅色低強度計時器。
休息時間。

HIIT 時間範例應用程式

在本章中,我建立了一個基本範例,也就是一個名為「HIIT Time」的 HIIT 計時器應用程式,讓使用者定義及管理各種計時器,這些計時器一律包含高強度和低強度間隔,然後選取其中一個計時器用於訓練課程。這是一個回應式應用程式,內含一個網格選單、一個分頁選單和三個頁面:

  • Workout:運動期間的有效頁面。可讓使用者選取其中一個計時器,並提供三個進度環:組合的數量、有效期間,以及休息時間。
  • 計時器:管理現有計時器,並讓使用者建立新的計時器。
  • 偏好設定:可讓您切換音效和語音輸出,以及選取語言和主題。

以下螢幕截圖可讓您瞭解應用程式的外觀。

以直向模式顯示的 HIIT Time 範例應用程式。
肖像模式中的「健身」分頁。
橫向模式的 HIIT Time 範例應用程式。
HIIT Time「Workout」分頁 (橫向模式)。
HIIT Time 範例應用程式,顯示計時器管理功能。
高強度間歇訓練計時器管理。

應用程式結構

如上所述,這個應用程式包含一個置頂工具列、一個分頁標題列和三個以格狀排列的頁面。導覽列和分頁列會以 iframe 實現,並在兩者之間加入 <div> 容器,以及三個用於網頁的 iframe,其中一個 iframe 會一律顯示,並依據分頁列中的有效選取項目。指向 about:blank 的最終 iframe 會針對動態建立的應用程式內頁面提供,需要修改現有計時器或建立新計時器。我稱這個模式為多頁單頁應用程式 (MPSPA)。

Chrome 開發人員工具檢視應用程式的 HTML 結構,顯示該結構由六個 iframe 組成:一個用於導覽列、一個用於分頁列,以及三個用於應用程式每個頁面的群組,最後一個則是用於動態頁面的預留位置 iframe。
應用程式包含六個 iframe。

元件式 lit-html 標記

每個網頁的結構會以 lit-html 支架的形式實現,並在執行階段動態評估。關於 lit-html 的背景資訊,它是 JavaScript 的一種高效、具表達力且可擴充的 HTML 範本庫。直接在 HTML 檔案中使用這項功能,即可讓心智編程模式直接以輸出為導向。程式設計師會編寫範本,決定最終輸出內容的外觀,而 lit-html 會根據您的資料動態填入空白,並連結事件監聽器。應用程式會使用第三方自訂元素,例如 Shoelace<sl-progress-ring>,或是自行實作的自訂元素 <human-duration>。由於自訂元素具有宣告式 API (例如進度環的 percentage 屬性),因此可與 lit-html 搭配使用,如下方清單所示。

<div>
  <button class="start" @click="${eventHandlers.start}" type="button">
    ${strings.START}
  </button>
  <button class="pause" @click="${eventHandlers.pause}" type="button">
    ${strings.PAUSE}
  </button>
  <button class="reset" @click="${eventHandlers.reset}" type="button">
    ${strings.RESET}
  </button>
</div>

<div class="progress-rings">
  <sl-progress-ring
    class="sets"
    percentage="${Math.floor(data.sets/data.activeTimer.sets*100)}"
  >
    <div class="progress-ring-caption">
      <span>${strings.SETS}</span>
      <span>${data.sets}</span>
    </div>
  </sl-progress-ring>
</div>
三個按鈕和進度環。
與上述標記對應的網頁轉譯區段。

程式設計模型

每個網頁都有對應的 Page 類別,可透過提供事件處理常式的實作方式,為 lit-html 標記填入資料,讓網頁充滿活力。這個類別也支援生命週期方法,例如 onShow()onHide()onLoad()onUnload()。網頁可以存取資料儲存庫,用於分享可選儲存的每個網頁狀態和全域狀態。所有字串都由中央管理,因此內建了國際化功能。瀏覽器會免費處理路由,因為應用程式只會切換 iframe 瀏覽權限,並針對動態建立的網頁變更預留位置 iframe 的 src 屬性。以下範例顯示用於關閉動態建立的頁面程式碼。

import Page from '../page.js';

const page = new Page({
  eventHandlers: {
    back: (e) => {
      e.preventDefault();
      window.top.history.back();
    },
  },
});
應用程式內頁面以 iframe 呈現。
瀏覽動作是從 iframe 到 iframe。

樣式

頁面樣式會在各自的 CSS 檔案中套用。這表示元素通常只能直接由元素名稱定址,因為不會與其他頁面有衝突。全域樣式會新增至每個網頁,因此您不必重複宣告 font-familybox-sizing 等主要設定。這也是定義主題和深色模式選項的地方。以下清單列出偏好設定頁面的規則,這些規則會在格狀檢視畫面中排列各種表單元素。

main {
  max-width: 600px;
}

form {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-gap: 0.5rem;
  margin-block-end: 1rem;
}

label {
  text-align: end;
  grid-column: 1 / 2;
}

input,
select {
  grid-column: 2 / 3;
}
HIIT Time 應用程式偏好設定頁面,顯示以格狀版面配置顯示的表單。
每一頁都是獨一無二的,您可以直接使用元素名稱設定樣式。

螢幕 Wake Lock

運動期間,螢幕不應關閉。在支援此功能的瀏覽器上,HIIT 時間會透過螢幕 Wake Lock 得知這一點。請參考下列程式碼片段,瞭解如何執行這項操作。

if ('wakeLock' in navigator) {
  const requestWakeLock = async () => {
    try {
      page.shared.wakeLock = await navigator.wakeLock.request('screen');
      page.shared.wakeLock.addEventListener('release', () => {
        // Nothing.
      });
    } catch (err) {
      console.error(`${err.name}, ${err.message}`);
    }
  };
  // Request a screen wake lock…
  await requestWakeLock();
  // …and re-request it when the page becomes visible.
  document.addEventListener('visibilitychange', async () => {
    if (
      page.shared.wakeLock !== null &&
      document.visibilityState === 'visible'
    ) {
      await requestWakeLock();
    }
  });
}

測試應用程式

您可以在 GitHub 上找到 HIIT Time 應用程式。您可以在新視窗中玩示範,也可以直接在下方的 iframe 嵌入中玩,這個 iframe 模擬了行動裝置。

特別銘謝

本文由 Joe MedleyKayce BasquesMilica MihajlijaAlan Kent 和 Keith Gu 共同審查。