在示例项目中运用迷你应用编程原则

应用网域

展示迷你应用的编程方式 我想做一个小小但足够完整的应用创意。 高强度间歇训练 (HIIT) 是一种心血管运动策略,包括交替进行一组短时间的剧烈有氧运动,但恢复时间较短。 许多 HIIT 训练都使用 HIIT 计时器,例如这个30 分钟的在线课程 来自 YouTube 上的“The Body Coach TV”频道。

<ph type="x-smartling-placeholder">
</ph> HIIT 训练在线课程,带有绿色的高强度计时器。 <ph type="x-smartling-placeholder">
</ph> 活跃期。
<ph type="x-smartling-placeholder">
</ph> HIIT 训练在线课程,带有红色低强度计时器。
静息期。

HIIT 时间示例应用

在本章中,我构建了一个基本的 HIIT 计时器应用示例,恰当地将其命名为 “HIIT 时间”让用户能够定义和管理各种计时器 始终由高强度和低强度间歇组成, 然后选择其中一个模型来进行培训课程 这是一款响应式应用,具有导航栏、标签页栏和三个页面:

  • 健身:锻炼期间的活动页面。它允许用户选择其中一个计时器 具有三个进度环:集合数、活动期和静息期。
  • 计时器:管理现有的计时器,并允许用户创建新计时器。
  • 偏好设置:允许切换音效和语音输出,以及选择语言和主题。

以下屏幕截图展示了该应用的外观。

<ph type="x-smartling-placeholder">
</ph> 竖屏模式下的 HIIT 时间示例应用。 <ph type="x-smartling-placeholder">
</ph> HIIT 时间“健身”进入竖屏模式
<ph type="x-smartling-placeholder">
</ph> 横屏模式下的 HIIT 时间示例应用。
HIIT 时间“健身”进入横屏模式
<ph type="x-smartling-placeholder">
</ph> HIIT 时间示例应用,显示计时器管理。
HIIT 时间计时器管理。

应用结构

如上所述,该应用由一个导航栏、一个标签页栏以及三个以网格形式排列的页面组成。 Navbar 和 Tabbar 以 iframe 的形式实现,两者之间有一个 <div> 容器,还有另外三个 iframe ,其中的网页始终可见,并且取决于选项卡栏中的活跃选择。 最终指向 about:blank 的 iframe 会为动态创建的应用内页面投放,而这是修改现有的应用内页面所必需的 或创建新的计时器 我将这种模式称为多页单页应用 (MPSPA)。

<ph type="x-smartling-placeholder">
</ph> Chrome DevTools 视图,其中显示了应用的 HTML 结构,其中显示了该应用包含 6 个 iframe:1 个用于导航栏、1 个用于标签页栏,以及 3 个已分组的 iframe 用于应用的每个页面,以及用于动态页面的最终占位符 iframe。 <ph type="x-smartling-placeholder">
</ph> 该应用包含 6 个 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 之间进行导航。

样式

页面样式设置是在每个页面自身的作用域 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 时间应用偏好设置页面。
每个网页都有自己的世界。样式设置直接通过元素名称进行。

屏幕唤醒锁定

锻炼期间,屏幕不应关闭。 在支持此功能的浏览器上,HIIT 时间通过屏幕唤醒锁定来实现这一点。 以下代码段展示了具体方法。

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();
    }
  });
}

测试应用

HIIT 时间应用可在 GitHub 上获取。 您可以在新窗口中查看该演示, 或直接插入下面的 iframe 嵌入内容(模拟移动设备)。

致谢

本文由以下人员审核: Joe Medley Kayce BasquesMilica MihajlijaAlan Kent, 和 Keith Gu。