דומיין האפליקציה
כדי להראות איך שיטת התכנות של אפליקציות מיני חלה על אפליקציית אינטרנט, נזקקתי לרעיון לאפליקציה קטנה אבל מספיק מלאה. אימון אינטרוולים בעצימות גבוהה (HIIT) הוא אסטרטגיה של אימון לב וכלי דם שמתבססת על סבבים של תקופות קצרות של אימון אנאירובי אינטנסיבי, שמחליפות תקופות מנוחה פחות אינטנסיביות. אימוני HIIT רבים מתבססים על שעוני HIIT. לדוגמה, הסשן הזה של 30 דקות אונליין מערוץ YouTube של The Body Coach TV.


אפליקציית דוגמה של HIIT Time
לצורך פרק זה, יצרתי דוגמה בסיסית לאפליקציית טיימר HIIT שנקראת 'HIIT Time'. האפליקציה מאפשרת למשתמש להגדיר ולנהל טיימר שונים, שתמיד מורכבים מאינטרוואל בעצימות גבוהה ואינטרוואל בעצימות נמוכה, ואז לבחור אחד מהם לסשן אימון. זוהי אפליקציה רספונסיבית עם סרגל ניווט, סרגל כרטיסיות ושלושה דפים:
- אימון: הדף הפעיל במהלך אימון. הממשק מאפשר למשתמש לבחור אחד מהטיימרים, ומוצגים בו שלושה טבעות התקדמות: מספר הסטים, התקופה הפעילה והתקופה של המנוחה.
- טיימרים: ניהול של טיימרים קיימים ומתן אפשרות למשתמשים ליצור טיימרים חדשים.
- העדפות: מאפשרות להפעיל או להשבית אפקטים של צלילים ופלט דיבור, ולבחור שפה ונושא.
צילומי המסך הבאים נותנים לכם מושג על האפליקציה.
מבנה האפליקציה
כפי שמתואר למעלה, האפליקציה מורכבת מסרגל ניווט, מסרגל כרטיסיות ושלושה דפים, שמסודרים בתצוגת רשת.
סרגל הניווט וסרגל הכרטיסיות מיושמים כמסגרות iframe עם מאגר <div>
ביניהן, עם שלוש מסגרות iframe נוספות לדפים, מתוכן אחת תמיד גלויה ותלויה בבחירה הפעילה בסרגל הכרטיסיות.
iframe סופי שמפנה אל about:blank
משמש לדפים בתוך האפליקציה שנוצרו באופן דינמי, שנדרשים כדי לשנות שעונים קיימים או ליצור שעונים חדשים.
אני מכנה את התבנית הזו 'אפליקציית דף יחיד עם כמה דפים' (MPSPA).

תגי עיצוב של lit-html מבוססי-רכיבים
המבנה של כל דף מוגדר בתבנית lit-html שמתבצעת הערכה דינמית שלה בזמן הריצה.
ספריית lit-html היא ספריית תבניות HTML יעילה, גמישה ומקיפה ל-JavaScript.
השימוש בו ישירות בקובצי ה-HTML הופך את מודל התכנות המנטלי ל-output-oriented.
כמ programers, אתם כותבים תבנית של המראה של הפלט הסופי, ואז ה-lit-html ממלא את הפערים באופן דינמי על סמך הנתונים שלכם ומחבר את רכיבי המעקב אחר האירועים.
האפליקציה משתמשת ברכיבים מותאמים אישית של צד שלישי, כמו <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()
.
לדפים יש גישה למאגר נתונים שמשמש לשיתוף מצב לכל דף ומצב גלובלי, אם רוצים לשמור אותם.
כל המחרוזות מנוהלות באופן מרכזי, כך שהתמיכה ב-Internationalization מובנית.
הניתוב מתבצע על ידי הדפדפן, למעשה בחינם, כי כל מה שהאפליקציה עושה הוא להחליף את החשיפה של ה-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 Time משתמשת בנעילת מסך כדי להשיג זאת. קטע הקוד הבא מראה איך עושים את זה.
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.