โดเมนของแอป
ถ้าอยากได้วิธีเขียนโปรแกรมมินิแอปที่ใช้กับเว็บแอป ผมจึงต้องการไอเดียเล็กๆ น้อยๆ เกี่ยวกับแอปให้สมบูรณ์มากพอ การออกกำลังกายแบบ HIIT (High-intensity interval training) เป็นกลยุทธ์การออกกำลังกายแบบคาร์ดิโอที่แบ่งเป็นชุดๆ โดยสลับกันระหว่างการออกกำลังกายแบบไม่ใช้ออกซิเจนอย่างหนักเป็นระยะเวลาสั้นๆ กับช่วงพักฟื้นที่หนักน้อยกว่า การฝึกแบบ HIIT หลายครั้งจะใช้ตัวจับเวลาแบบ HIIT เช่น ในเซสชันออนไลน์ 30 นาทีนี้ จากช่อง The Body Coach TV
แอปตัวอย่าง HIIT Time
สำหรับบทนี้ เราได้สร้างตัวอย่างพื้นฐานของแอปพลิเคชันตัวจับเวลา HIIT ที่ชื่อเหมาะเจาะว่า "HIIT Time" ซึ่งช่วยให้ผู้ใช้กำหนดและจัดการตัวจับเวลาต่างๆ ซึ่งประกอบด้วยช่วงที่มีระดับความเข้มข้นสูงและต่ำเสมอ จากนั้นเลือกตัวจับเวลาใดตัวหนึ่งสำหรับเซสชันการฝึก แอปนี้เป็นแอปที่ปรับเปลี่ยนตามอุปกรณ์ที่มีแถบนําทาง แถบแท็บ และ 3 หน้า ได้แก่
- การออกกำลังกาย: หน้าที่ใช้งานอยู่ระหว่างการออกกำลังกาย ซึ่งช่วยให้ผู้ใช้เลือกตัวจับเวลาได้ 1 รายการ และแสดงวงแหวนความคืบหน้า 3 วง ได้แก่ จํานวนชุด ระยะเวลาที่ใช้งาน และระยะเวลาพัก
- ตัวจับเวลา: จัดการตัวจับเวลาที่มีอยู่และอนุญาตให้ผู้ใช้สร้างตัวจับเวลาใหม่
- ค่ากำหนด: อนุญาตให้สลับเอฟเฟกต์เสียงและเอาต์พุตเสียงพูด รวมถึงการเลือกภาษาและธีม
ภาพหน้าจอต่อไปนี้แสดงถึงการแสดงผลของแอปพลิเคชัน
โครงสร้างแอป
ตามที่ระบุไว้ข้างต้น แอปนี้ประกอบด้วย Navbar, แถบแท็บ และหน้า 3 หน้าจัดเรียงอยู่ในตาราง
แถบนําทางและแถบแท็บจะแสดงเป็น iframe ที่มีคอนเทนเนอร์ <div>
อยู่ตรงกลาง โดยมี iframe อีก 3 รายการสําหรับหน้าเว็บ โดยจะมี 1 รายการที่แสดงอยู่เสมอและขึ้นอยู่กับการเลือกที่ใช้งานอยู่ในแถบแท็บ
IFrame สุดท้ายที่ชี้ไปยัง about:blank
แสดงสําหรับหน้าในแอปที่สร้างแบบไดนามิก ซึ่งจําเป็นสําหรับการแก้ไขตัวจับเวลาที่มีอยู่หรือสร้างใหม่
เราเรียกรูปแบบนี้ว่าแอปหน้าเดียวแบบหลายหน้า (MPSPA)
มาร์กอัป 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>
รูปแบบการเขียนโปรแกรม
แต่ละหน้าจะมีคลาส 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();
},
},
});
การจัดรูปแบบ
การจัดรูปแบบหน้าเว็บจะเกิดขึ้นในแต่ละหน้าในไฟล์ 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 จะตรวจจับสิ่งนี้ผ่านการล็อกหน้าจอ ข้อมูลโค้ดด้านล่างแสดงวิธีดำเนินการ
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