โดเมนของแอป
เพื่อแสดงวิธีเขียนโปรแกรมขนาดเล็กใน App ที่ใช้กับเว็บแอป ผมจำเป็นต้องมีแนวคิดแอปเล็กๆ แต่ครบถ้วนเพียงพอ การฝึกแบบช่วงความหนักหน่วงสูง (HIIT) เป็นกลยุทธ์การออกกำลังกายแบบคาร์ดิโอหลอดเลือด โดยจะสลับการออกกำลังกายแบบไม่ใช้ออกซิเจนแบบช่วงสั้นๆ ในช่วงเวลาสั้นๆ พร้อมช่วงฟื้นตัวที่น้อยลง การฝึก HIIT หลายรายการใช้ตัวจับเวลา HIIT เช่น เซสชันออนไลน์ 30 นาทีนี้จากช่อง YouTube ของ The Body Coach TV
![เซสชันออนไลน์การฝึก HIIT มีตัวจับเวลาความเข้มสูงสีเขียว](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-ed5b035be1093.png?authuser=6&hl=th)
![เซสชันออนไลน์การฝึก HIIT มีตัวจับเวลาความเข้มต่ำสีแดง](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-a0dd5340756f1.png?authuser=6&hl=th)
แอปตัวอย่างของ HIIT Time
ในบทนี้ ผมได้สร้างตัวอย่างเบื้องต้นของแอปพลิเคชันตัวจับเวลา HIIT ที่ตั้งชื่อได้อย่างเหมาะสมว่า "HIIT Time" ซึ่งให้ผู้ใช้กำหนดและจัดการตัวจับเวลาต่างๆ ประกอบด้วยช่วงความเข้มสูงและต่ำเสมอ แล้วเลือกมา 1 รายการสำหรับเซสชันการฝึก เป็นแอปที่ปรับเปลี่ยนตามอุปกรณ์ซึ่งมี Navbar, Tabbar และหน้า 3 หน้าดังนี้
- การออกกำลังกาย: หน้าที่มีการเคลื่อนไหวในระหว่างออกกำลังกาย ให้ผู้ใช้เลือกตัวจับเวลาอันใดอันหนึ่ง และมีวงกลมแสดงความคืบหน้า 3 อัน ได้แก่ จำนวนชุด ระยะเวลาที่ใช้งาน และระยะเวลาพัก
- ตัวจับเวลา: จัดการตัวจับเวลาที่มีอยู่และให้ผู้ใช้สร้างตัวจับเวลาใหม่
- ค่ากำหนด: อนุญาตให้สลับเอฟเฟกต์เสียงและเอาต์พุตเสียงพูด ตลอดจนเลือกภาษาและธีม
ภาพหน้าจอต่อไปนี้จะแสดงการแสดงผลของแอปพลิเคชัน
โครงสร้างแอป
ตามที่ระบุไว้ข้างต้น แอปประกอบด้วยแถบนำทาง แถบแท็บ และหน้า 3 หน้า โดยจัดเรียงแบบตารางกริด
ระบบจะจดจำ Navbar และ Tabbar เป็น iframe ที่มีคอนเทนเนอร์ <div>
คั่นกลาง โดยมี iframe อีก 3 รายการสำหรับหน้าเว็บ ซึ่งจะแสดงอยู่เสมอและขึ้นอยู่กับการเลือกที่ใช้งานอยู่ในแถบแท็บ
iframe สุดท้ายที่ชี้ไปยัง about:blank
จะแสดงในหน้าในแอปที่สร้างขึ้นแบบไดนามิก ซึ่งจำเป็นสำหรับการแก้ไขตัวจับเวลาที่มีอยู่หรือสร้างตัวจับเวลาใหม่
ฉันเรียกรูปแบบนี้ว่าแอปแบบหน้าเดียวแบบหลายหน้า (MPSPA)
![มุมมองเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ของโครงสร้าง HTML ของแอปแสดงให้เห็นว่าประกอบด้วย iframe 6 อัน ได้แก่ 1 อันสำหรับแถบนำทาง 1 อันสำหรับแถบแท็บ และอีก 3 รายการที่จัดกลุ่มไว้สำหรับแต่ละหน้าของแอป โดยมี iframe ตัวยึดตำแหน่งสุดท้ายสำหรับหน้าแบบไดนามิก](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/chrome-devtools-view-the-9da043317ba5b.png?authuser=6&hl=th)
มาร์กอัป lit-html ตามคอมโพเนนต์
ระบบจะมองว่าโครงสร้างของแต่ละหน้าเป็น Scaffold 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 ปุ่มและเสียงเรียกเข้าความคืบหน้า](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/three-buttons-a-progress-df2f6a20c093.png?authuser=6&hl=th)
โมเดลการเขียนโปรแกรม
แต่ละหน้าจะมีคลาส 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](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/in-app-page-realized-an-25ec73e15af7f.png?authuser=6&hl=th)
การจัดรูปแบบ
การจัดรูปแบบหน้าเว็บจะเกิดขึ้นตามหน้าเว็บแต่ละหน้าในไฟล์ 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 ที่แสดงแบบฟอร์มในเลย์เอาต์แบบตารางกริด](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-app-preferences-pag-3d83359174159.png?authuser=6&hl=th)
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 Time มีอยู่ใน GitHub คุณสามารถเล่นการสาธิตในหน้าต่างใหม่ หรือฝังใน iframe ด้านล่าง ซึ่งจะจำลองอุปกรณ์เคลื่อนที่
ข้อความแสดงการยอมรับ
บทความนี้ได้รับการตรวจสอบโดย Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent และ Keith Gu