החלת עקרונות התכנות של המיני אפליקציות בפרויקט לדוגמה

דומיין האפליקציה

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

שיעור אימוני HIIT אונליין עם טיימר ירוק בעצימות גבוהה.
תקופת הפעילות.
אימון HIIT אונליין עם טיימר אדום בעצימות נמוכה.
תקופת מנוחה.

אפליקציית דוגמה של HIIT Time

לצורך פרק זה, יצרתי דוגמה בסיסית לאפליקציית טיימר HIIT שנקראת 'HIIT Time'. האפליקציה מאפשרת למשתמש להגדיר ולנהל טיימר שונים, שתמיד מורכבים מאינטרוול בעצימות גבוהה ואינטרוול בעצימות נמוכה, ואז לבחור אחד מהם לסשן אימון. זוהי אפליקציה רספונסיבית עם סרגל ניווט, סרגל כרטיסיות ושלושה דפים:

  • אימון: הדף הפעיל במהלך אימון. הממשק מאפשר למשתמש לבחור אחד מהטיימרים, ומוצגים בו שלושה טבעות התקדמות: מספר הסטים, התקופה הפעילה והתקופה של המנוחה.
  • טיימרים: ניהול של טיימרים קיימים ומתן אפשרות למשתמשים ליצור טיימרים חדשים.
  • העדפות: מאפשרות להפעיל או להשבית אפקטים של צלילים ופלט דיבור, ולבחור שפה ונושא.

צילומי המסך הבאים נותנים לכם מושג על האפליקציה.

אפליקציה לדוגמה לזמן HIIT בפריסה לאורך.
כרטיסיית 'אימון' ב-HIIT Time במצב לאורך.
דוגמה לאפליקציה HIIT Time בפריסה לרוחב.
הכרטיסייה 'אימון' ב-HIIT Time במצב לרוחב.
אפליקציה לדוגמה של HIIT Time שמציגה ניהול של טיימר.
ניהול הטיימר של HIIT Time.

מבנה האפליקציה

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

תצוגה של כלי הפיתוח ל-Chrome במבנה ה-HTML של האפליקציה, שמראה שהיא מורכבת מ-6 מסגרות iframe: אחת לסרגל הניווט, אחת לסרגל הכרטיסיות ושלוש מסגרות לכל דף באפליקציה, עם placeholder סופי כ-iframe בדפים דינמיים.
האפליקציה מורכבת משש מסגרות iframe.

סימון 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();
    },
  },
});
דף באפליקציה שמוגדר כ-iframe.
הניווט מתבצע מ-iframe ל-iframe.

עיצוב

עיצוב הדפים מתבצע בכל דף בנפרד בקובץ 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, שבו מוצג טופס בפריסת רשת.
כל דף הוא עולם בפני עצמו. עיצוב מתבצע ישירות באמצעות שמות הרכיבים.

נעילה של מסך מצב שינה

במהלך אימון, המסך לא אמור לכבות. בדפדפנים שתומכים בכך, אפליקציית 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.