Domena aplikacji
Aby pokazać, jak programowanie miniaplikacji można zastosować w aplikacji internetowej, potrzebowałem małego, ale wystarczająco kompletnego pomysłu na aplikację. Trening interwałowy o wysokiej intensywności (HIIT) to strategia ćwiczeń sercowo-naczyniowych polegająca na naprzemiennych seriach krótkich okresów intensywnych ćwiczeń beztlenowych z mniej intensywnymi okresami regeneracji. Wiele treningów HIIT korzysta z timerów HIIT, np. ta 30-minutowa sesja online z kanału The Body Coach TV na YouTube.
Przykładowa aplikacja HIIT Time
Na potrzeby tego rozdziału stworzyłem podstawowy przykład takiej aplikacji z timerem HIIT o nazwie „HIIT Time”, która umożliwia użytkownikowi definiowanie i zarządzanie różnymi timerami, zawsze składającymi się z interwału o wysokiej i niskiej intensywności, a następnie wybranie jednego z nich na sesję treningową. Jest to aplikacja responsywna z paskiem nawigacyjnym, paskiem kart i 3 stronami:
- Trening: aktywna strona podczas treningu. Umożliwia użytkownikowi wybranie jednego z timerów i zawiera 3 pierścienie postępu: liczbę serii, okres aktywności i okres odpoczynku.
- Timery: zarządza istniejącymi timerami i umożliwia użytkownikowi tworzenie nowych.
- Ustawienia: umożliwia włączanie i wyłączanie efektów dźwiękowych i odpowiedzi głosowej, a także wybieranie języka i motywu.
Poniższe zrzuty ekranu dają wyobrażenie o aplikacji.
Struktura aplikacji
Jak wspomnieliśmy powyżej, aplikacja składa się z paska nawigacyjnego, paska kart i 3 stron ułożonych w siatce.
Pasek nawigacyjny i pasek kart są realizowane jako elementy iframe z kontenerem <div> między nimi i 3 kolejnymi elementami iframe
na strony. Jeden z nich jest zawsze widoczny i zależy od aktywnego wyboru na pasku kart.
Ostatni element iframe wskazujący about:blank służy do dynamicznego tworzenia stron w aplikacji, które są potrzebne do modyfikowania istniejących timerów lub tworzenia nowych.
Ten wzorzec nazywam aplikacją wielostronicową (MPSPA).
Znaczniki lit-html oparte na komponentach
Struktura każdej strony jest realizowana jako szkielet lit-html
który jest dynamicznie oceniany w czasie działania.
Lit-html to wydajna, ekspresywna i rozszerzalna biblioteka szablonów HTML dla JavaScriptu.
Dzięki używaniu jej bezpośrednio w plikach HTML model programowania mentalnego jest bezpośrednio zorientowany na dane wyjściowe.
Jako programista piszesz szablon tego, jak będą wyglądać dane wyjściowe, a lit-html dynamicznie wypełnia luki na podstawie Twoich danych i podłącza detektory zdarzeń.
Aplikacja korzysta z elementów niestandardowych innych firm, takich jak Shoelace's <sl-progress-ring> lub z samodzielnie zaimplementowanego elementu niestandardowego o nazwie <human-duration>.
Ponieważ elementy niestandardowe mają deklaratywny interfejs API (np. atrybut percentage okręgu postępu), dobrze współpracują z lit-html, co widać w poniższym przykładzie.
<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>
Model programowania
Każda strona ma odpowiadającą jej klasę Page, która wypełnia znaczniki lit-html, udostępniając implementacje obsługi zdarzeń i dane dla każdej strony.
Ta klasa obsługuje też metody cyklu życia, takie jak onShow(), onHide(), onLoad() i onUnload().
Strony mają dostęp do magazynu danych, który służy do udostępniania opcjonalnie utrwalonego stanu na stronie i stanu globalnego.
Wszystkie ciągi tekstowe są zarządzane centralnie, więc internacjonalizacja jest wbudowana.
Routing jest obsługiwany przez przeglądarkę zasadniczo bezpłatnie, ponieważ aplikacja tylko przełącza widoczność elementu iframe i w przypadku stron utworzonych dynamicznie zmienia atrybut src elementu iframe zastępczego.
Poniższy przykład pokazuje kod zamykania strony utworzonej dynamicznie.
import Page from '../page.js';
const page = new Page({
eventHandlers: {
back: (e) => {
e.preventDefault();
window.top.history.back();
},
},
});
Styl
Stylizacja stron odbywa się na każdej stronie w jej własnym pliku CSS o ograniczonym zakresie.
Oznacza to, że elementy można zwykle adresować bezpośrednio za pomocą ich nazw, ponieważ nie mogą wystąpić konflikty z innymi stronami.
Style globalne są dodawane do każdej strony, więc ustawienia centralne, takie jak font-family czy box-sizing, nie muszą być deklarowane wielokrotnie.
W tym miejscu definiowane są też motywy i opcje trybu ciemnego.
Poniższy przykład pokazuje reguły strony Ustawienia, które układają różne elementy formularza w siatce.
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;
}
Blokada uśpienia ekranu
Podczas treningu ekran nie powinien się wyłączać. W przeglądarkach, które to obsługują, aplikacja HIIT Time realizuje to za pomocą blokady wybudzania ekranu. Poniższy fragment kodu pokazuje, jak to zrobić.
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();
}
});
}
Testowanie aplikacji
Aplikacja HIIT Time jest dostępna na GitHub. Możesz wypróbować wersję demonstracyjną w nowym oknie, lub bezpośrednio w elemencie iframe poniżej, który symuluje urządzenie mobilne.
Podziękowania
Ten artykuł został sprawdzony przez Joe Medleya, Kayce Basques, Milicę Mihajliję, Alana Kenta, i Keitha Gu.