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

โดเมนของแอป

หากต้องการแสดงวิธีเขียนโปรแกรมแบบแอปขนาดเล็กที่ใช้กับเว็บแอป ฉันต้องมีไอเดียแอปเล็กๆ ที่สมบูรณ์พอ การออกกำลังกายแบบ 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 Time ในโหมดแนวนอน
ตัวอย่างแอป HIIT Time ที่แสดงการจัดการตัวจับเวลา
การจัดการตัวจับเวลา HIIT

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

ดังที่สรุปไว้ข้างต้น แอปประกอบด้วยแถบนําทาง แถบแท็บ และ 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 Time มีให้บริการใน GitHub คุณสามารถเล่นกับเดโมในหน้าต่างใหม่ หรือใน iframe ที่ฝังไว้ด้านล่าง ซึ่งจำลองอุปกรณ์เคลื่อนที่

ขอขอบคุณ

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