דומיין האפליקציה
כדי להראות את הדרך לתכנות באפליקציה מיני כשהחלתי על אפליקציית אינטרנט, היה לי צורך ברעיון קטן אבל מלא לאפליקציה. אימון אינטרוואלים בעצימות גבוהה (HIIT) היא אסטרטגיה של תרגילי קרדיו-וסקולריים שמורכבים מתקופות קצרות של אימון אנאירובי אינטנסיבי עם תקופות התאוששות פחות אינטנסיביות. הרבה הדרכות HIIT כוללות טיימרים של HIIT. למשל, סשן אונליין של 30 דקות מערוץ ה-YouTube של The Body Coach TV.
אפליקציה לדוגמה לזמן HIIT
עבור הפרק הזה, בניתי דוגמה בסיסית לאפליקציית טיימר HIIT בשם בצורה נכונה "זמן HIIT" שמאפשרת למשתמש להגדיר ולנהל טיימרים שונים, שכולל תמיד מרווח בעצימות גבוהה ונמוכה, ואז לבחור אחד מהם לסשן הדרכה. זוהי אפליקציה רספונסיבית עם סרגל ניווט, סרגל כרטיסיות ושלושה דפים:
- אימון: הדף הפעיל במהלך אימון הכושר. המשתמשים יכולים לבחור אחד מהטיימרים הוא כולל שלוש טבעות התקדמות: מספר הסטנדרים, התקופה הפעילה ותקופת המנוחה.
- טיימרים: ניהול הטיימרים הקיימים ומאפשר למשתמש ליצור טיימרים חדשים.
- העדפות: אפשר להפעיל או להשבית את האפקטים הקוליים ואת פלט הדיבור, ולבחור שפה ועיצוב.
צילומי המסך הבאים יוצרים רושם של האפליקציה.
מבנה האפליקציה
כפי שתואר קודם, האפליקציה מורכבת מסרגל ניווט, סרגל כרטיסיות ושלושה דפים, המסודרים ברשת.
סרגל הניווט וסרגל הטאבים מתפרשים כרכיבי iframe עם קונטיינר <div>
ביניהם, עם שלושה מסגרות iframe נוספות
של דפים, ומתוכם אפשר לראות אותם תמיד ותלויים בבחירה הפעילה שבסרגל הכרטיסיות.
iframe סופי שמפנה אל about:blank
משמש דפים שנוצרים באופן דינמי בתוך האפליקציה, שנדרשים כדי לשנות קיימים
או יצירת טיימרים חדשים.
אני קורא לתבנית הזו של אפליקציית דף יחיד עם מספר דפים (MPSPA).
תגי עיצוב lit-html שמבוססים על רכיבים
המבנה של כל דף מתואר כפילינג lit-html
שמוערך באופן דינמי בזמן הריצה.
כרקע ב-lit-html, זוהי ספרייה יעילה, בעלת הבעה והרחבה ל-JavaScript, שניתן להרחיב אותה.
שימוש בו ישירות בקובצי HTML מאפשר למודל התכנות הנפשי להתמקד ישירות בפלט.
כמתכנתים, אתם כותבים תבנית שמראה איך ייראה הפלט הסופי,
ו-lit-html ואז למלא את הפערים באופן דינמי על סמך הנתונים שלכם ולחבר את פונקציות ה-event 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>
מודל תכנות
לכל דף יש מחלקה תואמת Page
שממלאת את תגי העיצוב של lit-html באמצעות יישומים של הטמעות
של הגורמים המטפלים באירועים ולספק את הנתונים של כל דף.
הסיווג הזה תומך גם ב-methods של מחזור חיים כמו onShow()
, onHide()
, onLoad()
ו-onUnload()
.
לדפים יש גישה למאגר נתונים שמשמש לשיתוף באופן אופציונלי עם מצב קבוע ומצב גלובלי של כל דף.
כל המחרוזות מנוהלות באופן ריכוזי, כך שהאיחוד כבר מובנה.
הניתוב מתבצע על ידי הדפדפן ללא תשלום, מאחר שכל מה ש לעשות הוא להפעיל או להשבית את החשיפה ל-iframe
בדפים שנוצרים באופן דינמי, משנים את המאפיין src
של ה-iframe של ה-placeholder.
בדוגמה הבאה מוצג הקוד לסגירת דף שנוצר באופן דינמי.
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 הבא, שמדמה מכשיר נייד.
אישורים
המאמר הזה נבדק על ידי ג'ו מדלי, קייס בסקית, Milica Mihajlija, אלן קנט, וקית גו.