Uygulama alanı
Bir web uygulamasına uygulanan mini uygulama programlama yöntemini göstermek için küçük ama yeterince eksiksiz bir uygulama fikrine ihtiyacım vardı. Yüksek yoğunluklu aralıklı antrenman (HIIT), kısa süreli yoğun anaerobik egzersizlerin dönüşümlü olarak yapıldığı ve daha az yoğun toparlanma dönemleri içeren bir kardiyovasküler egzersiz stratejisidir. Çoğu HIIT eğitiminde HIIT zamanlayıcıları kullanılır. Örneğin, The Body Coach TV YouTube kanalındaki bu 30 dakikalık online oturum.
![Yeşil yüksek yoğunluklu zamanlayıcı ile HIIT eğitimi online oturumu.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-ed5b035be1093.png?authuser=6&hl=tr)
![Kırmızı düşük yoğunluklu zamanlayıcı ile HIIT eğitimi online oturumu.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-a0dd5340756f1.png?authuser=6&hl=tr)
HIIT Saati örnek uygulaması
Bu bölümde, kullanıcının her zaman yüksek ve düşük yoğunluklu çeşitli zamanlayıcılar tanımlayıp yönetmesine olanak tanıyan "HIIT Zamanı" adlı böyle bir HIIT zamanlayıcı uygulamasına ilişkin temel bir örnek oluşturdum ve daha sonra, eğitim oturumu için bunlardan birini seçtim. Bu bir gezinme çubuğu, bir sekme çubuğu ve üç sayfa içeren duyarlı bir uygulamadır:
- Antrenman: Antrenman sırasındaki etkin sayfa. Kullanıcının zamanlayıcılardan birini seçmesine olanak tanır ve üç ilerleme halkası içerir: set sayısı, etkin dönem ve dinlenme süresi.
- Zamanlayıcılar: Mevcut zamanlayıcıları yönetir ve kullanıcının yeni zamanlayıcılar oluşturmasına olanak tanır.
- Tercihler: Ses efektleri ile konuşma çıkışının açılıp kapatılmasına, dilin ve temanın seçilmesine olanak tanır.
Aşağıdaki ekran görüntüleri uygulamayla ilgili bir izlenim sağlar.
Uygulama yapısı
Yukarıda belirtildiği gibi uygulama, bir gezinme çubuğu, bir sekme çubuğu ve bir ızgara için düzenlenmiş üç sayfadan oluşur.
Gezinme çubuğu ve sekme çubuğu, aralarında bir <div>
kapsayıcısı bulunan iframe'ler olarak oluşur. Sayfalar için üç iframe daha içerir. Bunların her biri, her zaman görünür ve sekme çubuğundaki etkin seçime bağlıdır.
Dinamik olarak oluşturulan ve mevcut zamanlayıcıları değiştirmek veya yenilerini oluşturmak için gereken uygulama içi sayfalarda about:blank
öğesine işaret eden son bir iframe sunulur.
Bu kalıbı çok sayfalı tek sayfalık uygulama (MPSPA) olarak adlandırıyorum.
![Chrome Geliştirici Araçları'nda, uygulamanın altı iframe'den oluştuğunu gösteren HTML yapısının görünümü: gezinme çubuğu için bir iframe, sekme çubuğu için bir ve uygulamanın her sayfası için gruplandırılmış üç iframe ve dinamik sayfalar için son bir yer tutucu iframe.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/chrome-devtools-view-the-9da043317ba5b.png?authuser=6&hl=tr)
Bileşenlere dayalı lit-html işaretlemesi
Her sayfanın yapısı, çalışma zamanında dinamik olarak değerlendirilen lit-html yapısı olarak oluşturulur.
Lit-html'nin arka planı açısından, JavaScript için verimli, etkileyici, genişletilebilir bir HTML şablon kitaplığıdır.
Doğrudan HTML dosyalarında kullanıldığında zihinsel programlama modeli doğrudan çıkış odaklıdır.
Programcı olarak son çıktının nasıl görüneceğine dair bir şablon yazarsınız. Daha sonra lit-html, verilerinize dayanarak boşlukları dinamik olarak doldurur ve etkinlik işleyicilerin bağlantısını sağlar.
Uygulama, Ayakkabı Bağcığı'nın <sl-progress-ring>
öğesi veya <human-duration>
adlı kullanıcının kendi uyguladığı özel öğe gibi üçüncü taraflara ait özel öğeleri kullanıyor.
Özel öğelerin bildirim temelli bir API'si (örneğin, ilerleme halkasının percentage
özelliği) olduğundan, aşağıdaki listede görebileceğiniz gibi lit-html ile birlikte iyi çalışırlar.
<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>
![Üç düğme ve ilerleme halkası.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/three-buttons-a-progress-df2f6a20c093.png?authuser=6&hl=tr)
Programlama modeli
Her sayfada, etkinlik işleyicilerin uygulamalarını sağlayarak ve her sayfa için veri sağlayarak lit-html işaretlemesini hayatla dolduran karşılık gelen bir Page
sınıfı bulunur.
Bu sınıf onShow()
, onHide()
, onLoad()
ve onUnload()
gibi yaşam döngüsü yöntemlerini de destekler.
Sayfaların, isteğe bağlı olarak sayfa başına durumu ve genel durumu paylaşmaya hizmet eden bir veri deposuna erişimi vardır.
Tüm dizeler merkezi olarak yönetildiği için uluslararasılaştırma yerleşiktir.
Uygulama, iframe görünürlüğünü açıp kapattığı ve dinamik olarak oluşturulan sayfalar için yer tutucu iframe'in src
özelliğini değiştirdiği için yönlendirme, temelde tarayıcı tarafından ücretsiz olarak gerçekleştirilir.
Aşağıdaki örnekte, dinamik olarak oluşturulan bir sayfayı kapatmak için gereken kod gösterilmektedir.
import Page from '../page.js';
const page = new Page({
eventHandlers: {
back: (e) => {
e.preventDefault();
window.top.history.back();
},
},
});
![iframe olarak oluşturulan uygulama içi sayfa.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/in-app-page-realized-an-25ec73e15af7f.png?authuser=6&hl=tr)
Stil
Sayfaların stili, kendi kapsamlı CSS dosyasında sayfa bazında gerçekleşir.
Diğer sayfalarla çakışma olmayacağından bu, öğelerin genellikle doğrudan öğe adlarıyla ele alınabileceği anlamına gelir.
Genel stiller her sayfaya eklendiğinden, font-family
veya box-sizing
gibi merkezi ayarların tekrar tekrar bildirilmesine gerek yoktur.
Temalar ve koyu mod seçenekleri de burada tanımlanır.
Aşağıdaki listede, Tercihler sayfasının çeşitli form öğelerini bir ızgara üzerine yerleştiren kurallar gösterilmektedir.
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;
}
![Izgara düzeninde bir form gösteren HIIT Time uygulama tercihleri sayfası.](https://web.dev/static/articles/mini-apps/mini-app-example-project/image/hiit-app-preferences-pag-3d83359174159.png?authuser=6&hl=tr)
Ekran uyanık kalma kilidi
Antrenman sırasında ekran kapanmamalıdır. HIIT Time, bunu destekleyen tarayıcılarda bunu bir ekran uyanık kalma kilidi aracılığıyla algılar. Aşağıdaki snippet'te bunun nasıl yapıldığı gösterilmektedir.
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();
}
});
}
Uygulamayı test etme
HIIT Zamanı uygulaması GitHub'da bulunabilir. Demoyu yeni bir pencerede veya bir mobil cihazı simüle eden aşağıdaki iframe yerleşiminde oynayabilirsiniz.
Teşekkür
Bu makale, Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent ve Keith Gu tarafından incelenmiştir.