นำหลักการเขียนโปรแกรมแอปขนาดเล็กไปใช้กับโปรเจ็กต์ตัวอย่าง

โดเมนของแอป

เพื่อแสดงวิธีเขียนแอปขนาดเล็ก ที่ใช้กับเว็บแอป ผมต้องการแนวคิดเล็กๆ น้อยๆ ที่ครบถ้วนแต่ก็เพียงพอ การออกกำลังที่มีความเข้มข้นสูง (HIIT) เป็นกลยุทธ์การออกกำลังกายด้วยหัวใจและหลอดเลือดแบบสลับการออกกำลังกายเป็นช่วงสั้นๆ แบบไม่ใช้ออกซิเจนแบบหนักหน่วงโดยมีระยะเวลาการฟื้นตัวน้อยลง การฝึกแบบ HIIT หลายครั้งจะใช้ตัวจับเวลาแบบ HIIT เช่น เซสชันออนไลน์ 30 นาทีนี้ จากช่อง YouTube ของ The Body Coach TV

วันที่ เซสชันการฝึก HIIT ออนไลน์ด้วยตัวจับเวลาความเข้มข้นสูงสีเขียว
ระยะเวลาที่ใช้งาน
เซสชันการฝึก HIIT ออนไลน์ด้วยตัวจับเวลาความเข้มระดับต่ำสีแดง
ระยะเวลาพัก

แอปตัวอย่าง HIIT Time

สำหรับบทนี้ ฉันได้สร้างตัวอย่าง พื้นฐานของแอปพลิเคชันตัวจับเวลา HIIT ขึ้นมา "เวลา HIIT" ซึ่งให้ผู้ใช้กำหนดและจัดการตัวจับเวลาต่างๆ ประกอบไปด้วยช่วงความเข้มสูงและต่ำเสมอ แล้วเลือกมา 1 รายการสำหรับเซสชันการฝึกอบรม เป็นแอปที่ปรับเปลี่ยนตามอุปกรณ์ ซึ่งมี Navbar, Tabbar และหน้า 3 หน้า

  • การออกกำลังกาย: หน้าที่ใช้งานอยู่ระหว่างการออกกำลังกาย ให้ผู้ใช้เลือกตัวจับเวลาอันใดอันหนึ่งได้ และจะแสดงวงแหวนแสดงความคืบหน้า 3 วง ได้แก่ จำนวนชุด ระยะเวลาที่ใช้งาน และระยะเวลาที่เหลือ
  • ตัวจับเวลา: จัดการตัวจับเวลาที่มีอยู่และให้ผู้ใช้สร้างตัวจับเวลาใหม่
  • ค่ากำหนด: อนุญาตให้สลับเอฟเฟกต์เสียงและเอาต์พุตเสียงพูด รวมถึงการเลือกภาษาและธีม

ภาพหน้าจอต่อไปนี้แสดงถึงการแสดงผลของแอปพลิเคชัน

วันที่ ตัวอย่างแอป HIIT Time ในโหมดแนวตั้ง
เวลา HIIT "ออกกำลังกาย" แท็บในโหมดแนวตั้ง
ตัวอย่างแอป HIIT Time ในโหมดแนวนอน
เวลา HIIT "ออกกำลังกาย" แท็บในโหมดแนวนอน
แอปตัวอย่าง HIIT Time ที่แสดงการจัดการตัวจับเวลา
การจัดการตัวจับเวลาแบบ HIIT

โครงสร้างแอป

ตามที่ระบุไว้ข้างต้น แอปนี้ประกอบด้วย Navbar, แถบแท็บ และหน้า 3 หน้าจัดเรียงอยู่ในตาราง ระบบรู้จัก Navbar และ Tabbar ว่าเป็น iframe ที่มีคอนเทนเนอร์ <div> อยู่ระหว่างคอนเทนเนอร์และมี iframe อีก 3 รายการ สำหรับหน้าเว็บ โดยจะแสดงหน้าเว็บใดอยู่เสมอและขึ้นอยู่กับการเลือกที่ทำงานอยู่ในแถบแท็บ iframe สุดท้ายที่ชี้ไปยัง about:blank จะแสดงสําหรับหน้าในแอปที่สร้างขึ้นแบบไดนามิก ซึ่งจําเป็นสําหรับการแก้ไขที่มีอยู่ หรือการสร้างตัวจับเวลาใหม่ ฉันเรียกรูปแบบนี้ว่าแอปแบบหน้าเดียวแบบหลายหน้า (MPSPA)

วันที่ มุมมองเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ของโครงสร้าง HTML ของแอปที่แสดงให้เห็นว่าประกอบด้วย iframe ทั้งหมด 6 รายการ ได้แก่ iframe 1 รายการสำหรับ Navbar, 1 รายการสำหรับแถบแท็บ และ 3 รายการที่จัดกลุ่มสำหรับแต่ละหน้าของแอป โดยมี iframe ตัวยึดตำแหน่งสุดท้ายสำหรับหน้าแบบไดนามิก
แอปประกอบด้วย iframe 6 รายการ

มาร์กอัป lit-html ตามคอมโพเนนต์

โครงสร้างของแต่ละหน้าเรียกว่า lit-html ที่ได้รับการประเมินแบบไดนามิกขณะรันไทม์ สำหรับพื้นหลังเกี่ยวกับ lit-html ไลบรารีนี้จัดเป็นไลบรารีเทมเพลต HTML ที่มีประสิทธิภาพ ชัดเจน และขยายได้สำหรับ JavaScript เมื่อใช้ได้โดยตรงในไฟล์ HTML โมเดลการเขียนโปรแกรมทางจิตวิทยาจะเน้นเอาต์พุตโดยตรง ในฐานะโปรแกรมเมอร์ คุณเขียนเทมเพลตว่าผลลัพธ์สุดท้ายจะเป็นอย่างไร และ lit-html แล้วเติมเต็มช่องว่างนั้นแบบไดนามิกโดยอิงตามข้อมูลของคุณ และดึงดูด Listener เหตุการณ์ แอปใช้ประโยชน์จากองค์ประกอบที่กำหนดเองของบุคคลที่สาม เช่น <sl-progress-ring> ของ Shoelace หรือองค์ประกอบที่กำหนดเองแบบติดตั้งด้วยตนเองที่เรียกว่า <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>
ปุ่ม 3 ปุ่มและวงแหวนแสดงความคืบหน้า
ส่วนที่แสดงผลของหน้าที่สอดคล้องกับมาร์กอัปด้านบน

โมเดลการเขียนโปรแกรม

แต่ละหน้ามีคลาส Page ที่เกี่ยวข้องซึ่งเติมมาร์กอัป lit-html ให้มีชีวิตชีวาด้วยการนำเสนอการนำไปใช้งาน ของเครื่องจัดการเหตุการณ์และให้ข้อมูลสำหรับแต่ละหน้า คลาสนี้ยังรองรับวิธีใช้ตลอดอายุการใช้งาน เช่น onShow(), onHide(), onLoad() และ onUnload() ด้วย หน้าเว็บมีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลซึ่งทำหน้าที่แชร์ (ไม่บังคับ) ต่อสถานะต่อหน้าเว็บและสถานะส่วนกลาง สตริงทั้งหมดได้รับการจัดการจากส่วนกลาง จึงมีการปรับให้เป็นสากลในตัว เบราว์เซอร์จะจัดการการกำหนดเส้นทางโดยไม่เสียค่าใช้จ่ายเป็นหลัก เนื่องจากแอปทั้งหมดทำได้โดยการสลับการเปิดเผย iframe และ สำหรับหน้าที่สร้างขึ้นแบบไดนามิก ให้เปลี่ยนแอตทริบิวต์ src ของตัวยึดตำแหน่ง iframe ตัวอย่างด้านล่างแสดงโค้ดสำหรับการปิดหน้าเว็บที่สร้างขึ้นแบบไดนามิก

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

const page = new Page({
  eventHandlers: {
    back: (e) => {
      e.preventDefault();
      window.top.history.back();
    },
  },
});
รับรู้หน้าในแอปเป็น iframe
การไปยังส่วนต่างๆ เกิดขึ้นจาก iframe ไปยัง iframe

การจัดรูปแบบ

การจัดรูปแบบหน้าเว็บจะเกิดขึ้นในแต่ละหน้าในไฟล์ CSS ที่มีขอบเขตของตนเอง ซึ่งหมายความว่าโดยปกติแล้วองค์ประกอบต่างๆ จะสามารถระบุด้วยชื่อองค์ประกอบได้โดยตรง เพราะจะไม่เกิดการชนกับหน้าอื่นๆ ได้ สไตล์ส่วนกลางจะเพิ่มลงในแต่ละหน้า ดังนั้นการตั้งค่าส่วนกลาง เช่น font-family หรือ box-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 Time จะทราบข้อมูลนี้ผ่าน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();
    }
  });
}

การทดสอบแอปพลิเคชัน

แอปพลิเคชันเวลา HIIT มีให้บริการใน GitHub เล่นการสาธิตในหน้าต่างใหม่ หรือใน iframe ที่ฝังด้านล่าง ซึ่งจะจำลองอุปกรณ์เคลื่อนที่

กิตติกรรมประกาศ

บทความนี้ได้รับการตรวจสอบโดย Joe Medley Kayce Basques Milica Mihajlija Alan Kent และ Keith Gu