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

โดเมนของแอป

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

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

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

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

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

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

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

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

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

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

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

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

ล็อกการปลุกหน้าจอ

หน้าจอไม่ควรปิดระหว่างออกกำลังกาย ในเบราว์เซอร์ที่รองรับ ฟีเจอร์เวลา 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 Basques, Milica Mihajlija, Alan Kent และ Keith Gu