דומיין האפליקציה
כדי להראות את התכנות בסגנון אפליקציות מיני באפליקציית אינטרנט, נזקקתי לרעיון לאפליקציה קטנה אבל מספיק מלאה. אימון אינטרוולים בעצימות גבוהה (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, זוהי ספרייה יעילה, בעלת הבעה והרחבה ל-JavaScript, שניתן להרחיב אותה.
שימוש בו ישירות בקובצי HTML מאפשר למודל התכנות הנפשי להתמקד ישירות בפלט.
כמ 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.