<dialog>
öğesiyle renge uyarlanan, duyarlı ve erişilebilir mini ve mega kalıcı öğelerin nasıl oluşturulacağına dair temel bir genel bakış.
Bu gönderide, renge uyum sağlayan tasarımla ilgili
düşüncelerimi paylaşmak istiyorum.
duyarlı ve erişilebilir mini ve mega modaller (<dialog>
) içerir.
Demoyu deneyin ve şu içeriği görüntüleyin:
kaynak!
Video kullanmayı tercih ederseniz bu gönderinin YouTube versiyonunu kullanabilirsiniz:
Genel Bakış
İlgili içeriği oluşturmak için kullanılan
<dialog>
öğesi, sayfa içi bağlamsal bilgiler veya işlemler için idealdir. Projenin gidişatı boyunca
Kullanıcı deneyiminde, birden fazla sayfa yerine aynı sayfa işleminden yararlanılabilir.
olabilir: Belki formun küçük olması veya
onaylamak veya iptal etmektir.
<dialog>
öğesi kısa süre önce tüm tarayıcılarda kararlı hale geldi:
Öğede bazı şeylerin eksik olduğunu fark ettim. Bu GUI'de Zorluk Geliştirici deneyimini ekliyorum beklediğim öğeler: ek etkinlikler, ışık kapatma, özel animasyonlar ve mini avatar bir seçimdir.
Brüt kar
Bir <dialog>
öğesinin temel özellikleri mütevazıdır. Öğe
otomatik olarak gizlenir ve içeriğinizle yer paylaşımlı olacak şekilde yerleşik stillere sahiptir.
<dialog>
…
</dialog>
Bu temel değeri iyileştirebiliriz.
Geleneksel olarak, iletişim öğesi öğesi, kalıcı bir iletişim öğesi ile çok fazla şey paylaşır ve genellikle adlar
özellikler birbirinin yerine kullanılabilir. Burada diyalog öğesini
kullanma özgürlüğünü kazandım.
iletişim kutusu pop-up'ları (mini) ve tam sayfa iletişim kutuları (mega) gösterilir. Adlandırdım
her iki diyalog da farklı kullanım alanlarına göre biraz uyarlandı.
Türü belirtmenize olanak tanımak için bir modal-mode
özelliği ekledim:
<dialog id="MegaDialog" modal-mode="mega"></dialog>
<dialog id="MiniDialog" modal-mode="mini"></dialog>
Her zaman değil ancak genellikle bazı bilgileri toplamak için diyalog öğeleri kullanılır
daha fazla bilgi edineceksiniz. İletişim kutusu öğelerinin içindeki formlar kullanıma uygun hale getirildi
birlikte kullanılabilir.
İletişim kutusu içeriğini
JavaScript, kullanıcının girdiği verilere erişebilir. Ayrıca, içindeki düğmeler
method="dialog"
kullanan bir form JavaScript olmadan bir iletişim kutusunu kapatabilir ve
dışı verilerdir.
<dialog id="MegaDialog" modal-mode="mega">
<form method="dialog">
…
<button value="cancel">Cancel</button>
<button value="confirm">Confirm</button>
</form>
</dialog>
Mega iletişim kutusu
Mega bir iletişim kutusunun içinde üç öğe bulunur:
<header>
<article>
,
ve
<footer>
.
Bunlar anlamsal kapsayıcıların yanı sıra
diyaloglarının
sunumunu ele alacağız. Üstbilgi, kalıcı öğeyi adlandırıyor ve
düğmesini tıklayın. Bu makale, form girişleri ve bilgiler içindir. Altbilgide bir
<menu>
/
işlem düğmeleridir.
<dialog id="MegaDialog" modal-mode="mega">
<form method="dialog">
<header>
<h3>Dialog title</h3>
<button onclick="this.closest('dialog').close('close')"></button>
</header>
<article>...</article>
<footer>
<menu>
<button autofocus type="reset" onclick="this.closest('dialog').close('cancel')">Cancel</button>
<button type="submit" value="confirm">Confirm</button>
</menu>
</footer>
</form>
</dialog>
İlk menü düğmesinde
autofocus
ve onclick
satır içi etkinlik işleyicisi. autofocus
özelliği
odaklanacağım. Bunu en iyi uygulama olarak düşünüyorum.
onaylama düğmesine değil, iptal düğmesine basın. Bu, onayın
kasten yapılmış olabilir.
Mini iletişim kutusu
Mini iletişim kutusu mega diyaloğa çok benziyor, yalnızca
<header>
öğesi. Bu, daha küçük ve daha satır içi olmasına olanak tanır.
<dialog id="MiniDialog" modal-mode="mini">
<form method="dialog">
<article>
<p>Are you sure you want to remove this user?</p>
</article>
<footer>
<menu>
<button autofocus type="reset" onclick="this.closest('dialog').close('cancel')">Cancel</button>
<button type="submit" value="confirm">Confirm</button>
</menu>
</footer>
</form>
</dialog>
İletişim öğesi, tüm görüntü alanı öğeleri için güçlü bir temel sağlar. veri ve kullanıcı etkileşimini toplayabilir. Bu temel ihtiyaçlar, bir proje yöneticisinin güçlü etkileşimler oluşturabilirsiniz.
Erişilebilirlik
İletişim öğesinin yerleşik erişilebilirliği çok iyi. Bunları eklemek yerine gibi birçok özellik zaten mevcut.
Odak geri yükleniyor
Yan gezinme bölümü oluşturma bileşenine yer verdikten sonra Bir şeyi doğru şekilde açıp kapatmak, ilgili açılış ve kapanış aşamasına odaklanır düğmelerini kullanın. Yan gezinme paneli açıldığında odak, kapat düğmesine getirilir. Kapat düğmesine basıldığında, odak, düğmeyi açan düğmeye geri döner.
İletişim kutusunda bu, yerleşik varsayılan davranıştır:
Ne yazık ki iletişim kutusunu içeri ve dışarı taşımak istiyorsanız bu işlev kayboldu. JavaScript bölümünde, bu kodu geri yükleyeceğim. işlevi görür.
Odak yakalama
İletişim öğesi,
inert
sizin için kullanılabilir. inert
öncesinde odaklanmayı izlemek için JavaScript kullanılıyordu
bir öğe bırakır ve bu noktada araya girer ve onu geri koyar.
inert
tarihinden sonra belgenin tüm bölümleri "dondurulabilir" onlar için çok büyük.
hedeflere odaklanmaz veya fare ile etkileşime girer. Hikayeyi
dokümanın etkileşimli tek bölümüne yönlendirilir.
Bir öğeyi açma ve otomatik olarak odaklama
Varsayılan olarak, iletişim öğesi odağı ilk odaklanılabilir öğeye atar
iletişim kutusu işaretlemesinde. Bu, kullanıcının varsayılan olarak ayarlayabileceği en iyi öğe değilse
autofocus
özelliğini kullanın. Daha önce de belirttiğim gibi bunun en iyi uygulama olarak
bunu onaylama düğmesine değil, iptal düğmesine koyun. Böylece proje daha
kasıtlı olarak yapılan onaydır. Yanlışlıkla yapılan bir onay değildir.
Escape tuşuyla kapatma
Rahatsız edici olabilecek bu öğenin kolayca kapatılması önemlidir. Neyse ki iletişim öğesi, escape tuşuna basarak sizin yerinize bu sayede organize etme yükünden kurtulursunuz.
Stiller
İletişim öğesinin stilini ayarlamanın kolay bir yolu ve sabit bir yolu vardır. Kolay
yolu, iletişim kutusunun görüntüleme özelliğinin değiştirilip çalışmamasıyla elde edilir
sahip olabilirsiniz. Özel animasyonlar sağlamak için
iletişim kutusu açılıp kapatılarak display
mülkü ve başka alanlar devralınır.
Açık Sahnelerle Stil
Uyarlanabilir renkleri ve genel tasarım tutarlılığını hızlandırmak için CSS değişken kitaplığım Open Props'u getirdi. İçinde ücretsiz sağlanan değişkenlere ek olarak, normalize dosyası ve bazı Her ikisi de Open Props olan buttons isteğe bağlı içe aktarma işlemleri olarak sunar. Bu içe aktarma işlemleri sayesinde, göstermek için çok fazla stile ihtiyaç duymadan diyalog ve demo iyi.
<dialog>
öğesinin stilini belirleme
Görüntülü reklam mülküne sahip olma
Bir iletişim öğesinin varsayılan gösterme ve gizleme davranışı, ekranı açar/kapatır
mülkü block
-none
arasında. Maalesef bu videoda animasyon
yalnızca içeride, içeride. Hem içeri hem de çıkış animasyonu eklemek istiyorum. İlk adım
kendiminkini
display mülkü:
dialog {
display: grid;
}
Görüntülü Reklam Ağı mülkünün değerini değiştirerek ve dolayısıyla sahip olduğunuzda, JavaScript snippet'inin üst kısmında yer alması için çok sayıda stilin uygun kullanıcı deneyimini kolaylaştırma. Öncelikle, iletişim kutusunun varsayılan durumu kapalı. Bu durumu görsel olarak gösterebilir ve iletişim kutusunun şu stillerle etkileşimler alınıyor:
dialog:not([open]) {
pointer-events: none;
opacity: 0;
}
Artık iletişim kutusu görünmez ve açık değilken etkileşimde bulunulamaz. Daha sonra
İletişim kutusunda inert
özelliğini yönetmek için birkaç JavaScript ekleyeceğim.
Ayrıca, klavye ve ekran okuyucu kullanıcılarının da gizli iletişim kutusuna
erişemezler.
Diyaloğa uyarlanabilir bir renk teması ekleme
color-scheme
, dokümanınızı tarayıcı tarafından sağlanan bir tarayıcıda etkinleştirirken
renk temasını açık ve koyu sistem tercihlerine göre özelleştirdim.
daha fazla olduğunu düşünelim. Open Props size birkaç yüzey sağlar
otomatik olarak uyarlanan renkler
açık ve koyu sistem tercihlerini
color-scheme
kullanmaya benzer. Bu
bir tasarımda katmanlar oluşturmak için harika.
katman yüzeylerinin bu görünümünü görsel olarak destekler. Arka plan rengi
var(--surface-1)
; üst kısmına taşımak için var(--surface-2)
işlevini kullanın:
dialog {
…
background: var(--surface-2);
color: var(--text-1);
}
@media (prefers-color-scheme: dark) {
dialog {
border-block-start: var(--border-size-1) solid var(--surface-3);
}
}
Başlık gibi alt öğeler için daha sonra daha uyarlanabilir renkler eklenir kullanabilirsiniz. Ben bunları bir diyalog öğesi için daha fazla iyi tasarlanmış bir diyalog tasarımı yapmak.
Duyarlı iletişim kutusu boyutlandırma
İletişim kutusu varsayılan olarak boyutunu içeriklerine verir. Bu da genellikle
harika. Buradaki amacım
max-inline-size
okunabilir bir boyuta (--size-content-3
= 60ch
) veya görüntü alanı genişliğinin% 90'ına ayarlayın. Bu
iletişimin mobil cihazlarda uçtan uca gitmemesini ve
görüntülenmeleri zor olabilir. Daha sonra
max-block-size
Böylece iletişim kutusu sayfanın yüksekliğini aşmaz. Bu, aynı zamanda
iletişim kutusunun kaydırılabilir alanının
yerini belirtmeniz gerekir (ör. uzun bir metin
iletişim kutusu öğesini seçin.
dialog {
…
max-inline-size: min(90vw, var(--size-content-3));
max-block-size: min(80vh, 100%);
max-block-size: min(80dvb, 100%);
overflow: hidden;
}
İki kez max-block-size
aboneliğimin olduğunu fark ettiniz mi? İlki 80vh
, fiziksel bir
görüntü alanı birimi. Aslında istediğim, diyaloğu göreli bir akış içinde tutmak,
Bu yüzden, ben mantıklı, yeni ve sadece kısmen
daha kararlı hale geldiği zaman için ikinci beyanda dvb
birimi desteklenmiştir.
Mega iletişim kutusu konumlandırma
Bir iletişim öğesinin konumlandırılmasına yardımcı olması için iki küçük parçalar: tam ekran arka planı ve iletişim kutusu kapsayıcısı. Arka plan, her şeyi kapsayan bir gölge efekti sağlayarak ve arkadaki içeriğe ulaşılamıyor. İletişim kapsayıcısında dilediğiniz zaman bu arka plan üzerinde ortalayarak içeriğin gerektirdiği şekilde şekillendirebilir.
Aşağıdaki stiller, iletişim öğesini pencereye sabitleyerek her bir boyuta genişletilir
ve içeriği ortalamak için margin: auto
kullanır:
dialog {
…
margin: auto;
padding: 0;
position: fixed;
inset: 0;
z-index: var(--layer-important);
}
Mobil mega iletişim kutusu stilleri
Küçük görüntü alanlarında, bu tam sayfa mega pencereyi biraz farklı şekilde biçimlendiriyorum. İ
alt kenar boşluğunu 0
olarak ayarla, bu sayede iletişim kutusu içeriği sayfanın en altına konacak
görüntü alanını değiştirebilirsiniz. Birkaç stil ayarlamasıyla iletişim kutusunu
hareket sayfasını kullanıcının baş parmaklarına yaklaştırın:
@media (max-width: 768px) {
dialog[modal-mode="mega"] {
margin-block-end: 0;
border-end-end-radius: 0;
border-end-start-radius: 0;
}
}
Mini iletişim kutusu konumlandırma
Masaüstü bilgisayar gibi daha büyük bir görüntü alanı kullanırken, mini iletişim kutularını onları çağıran öğedir. Bunun için JavaScript'e ihtiyacım var. Web sitenizin kullandığım teknik buradan Ancak bunun bu makalenin kapsamı dışında olduğunu düşünüyorum. JavaScript olmadan mini iletişim kutusu, mega iletişim kutusu gibi ekranın ortasında görünür.
Çarpıcı hale getirin
Son olarak, iletişim kutusunu çok uzağa uzanmış yumuşak bir yüzey gibi görünecek şekilde zenginleştirin dokunun. Yumuşaklık, iletişim kutusunun köşeleri yuvarlanarak elde edilir. Derinlik, Open Props'un özenle hazırlanmış gölgesinden biriyle elde ediliyor öğeler:
dialog {
…
border-radius: var(--radius-3);
box-shadow: var(--shadow-6);
}
Sözde arka plan öğesini özelleştirme
Arka plan üzerinde çok hafif çalışmayı seçtim. Yalnızca arka plandaki
backdrop-filter
mega iletişim kutusuna geç:
dialog[modal-mode="mega"]::backdrop {
backdrop-filter: blur(25px);
}
Ayrıca backdrop-filter
için bir geçiş yapmayı seçtim. Umarım tarayıcıların
arka plan öğesinin ileride geçişine olanak tanır:
dialog::backdrop {
transition: backdrop-filter .5s ease;
}
Stil ekstraları
Bu bölüme "ekstralar" adını veriyorum. çünkü iletişim öğemle daha çok alakalı daha fazla demo yapmaktır.
Kaydırma kapsamı
İletişim kutusu gösterildiğinde kullanıcı, arkasındaki sayfayı kaydırmaya devam edebilir. istemediğim bir şey var:
Normalde
overscroll-behavior
her zamanki çözümümdür ancak aboneliğe göre
spesifikasyon,
üzerinde herhangi bir etkisi yoktur. Çünkü bu bir kaydırma bağlantı noktası değildir,
olmadığından emin olun. JavaScript kullanarak
bu kılavuzdaki yeni etkinlikler (ör. "closed") ve "opened" seçenekleri yer alır.
overflow: hidden
veya :has()
adlı kullanıcının
tüm tarayıcılar:
html:has(dialog[open][modal-mode="mega"]) {
overflow: hidden;
}
Artık mega iletişim kutusu açıkken html dokümanında overflow: hidden
olur.
<form>
düzeni
Paydaşlarla etkileşimi toplamak için çok önemli bir öğe
buradan başlık, altbilgi ve görünüm düzenlemelerini
makale öğelerinden yararlanabilirsiniz. Bu sayfa düzeniyle, makalenin altını bir
kaydırılabilir alan. Bunu başarmak için
grid-template-rows
.
Makale öğesine 1fr
verilmiş ve formun kendisi için aynı maksimum değer
yüksekliği ile aynı olmalıdır. Bu firma yüksekliğini ve sabit satır boyutunu ayarlamak için
makale öğesinin sınırlanmasına ve taştığında kaymasına olanak tanır:
dialog > form {
display: grid;
grid-template-rows: auto 1fr auto;
align-items: start;
max-block-size: 80vh;
max-block-size: 80dvb;
}
İletişim kutusunun stilini belirleme <header>
Bu öğenin rolü, diyalog içeriği ve teklif için bir başlık sağlamaktır. kolayca bulunabilen bir kapat düğmesi ekleyin. Ayrıca görünmesini sağlamak için bir yüzey rengi de verilmiştir olması gerektiğini unutmayın. Bu gereksinimler, bir flexbox'ın kenarlarına yerleştirilmiş dikey olarak hizalı öğeler ve dolgu ve boşluklar kullanarak başlık ve kapatma düğmelerine biraz alan bırakır:
dialog > form > header {
display: flex;
gap: var(--size-3);
justify-content: space-between;
align-items: flex-start;
background: var(--surface-2);
padding-block: var(--size-3);
padding-inline: var(--size-5);
}
@media (prefers-color-scheme: dark) {
dialog > form > header {
background: var(--surface-1);
}
}
Başlığı kapatma düğmesinin stilini belirleme
Demoda Open Props düğmelerini kullandığından kapatma düğmesi özelleştirilmiştir şu şekilde yuvarlak, simge merkezli bir düğmeye dönüşür:
dialog > form > header > button {
border-radius: var(--radius-round);
padding: .75ch;
aspect-ratio: 1;
flex-shrink: 0;
place-items: center;
stroke: currentColor;
stroke-width: 3px;
}
İletişim kutusunun stilini belirleme <article>
Makale öğesinin bu iletişim kutusunda özel bir rolü vardır: uzun veya uzun bir iletişim kutusundaysa kaydırılamaz.
Bunu sağlamak için üst form öğesi, dönüşüm izleme için
Bu makale öğesinin kendisi
çok uzun. Kaydırma çubuklarının yalnızca gerektiğinde gösterileceği şekilde overflow-y: auto
özelliğini ayarlayın.
içinde overscroll-behavior: contain
ile kaydırma içerir ve
özel sunu stilleri olacaktır:
dialog > form > article {
overflow-y: auto;
max-block-size: 100%; /* safari */
overscroll-behavior-y: contain;
display: grid;
justify-items: flex-start;
gap: var(--size-3);
box-shadow: var(--shadow-2);
z-index: var(--layer-1);
padding-inline: var(--size-5);
padding-block: var(--size-3);
}
@media (prefers-color-scheme: light) {
dialog > form > article {
background: var(--surface-1);
}
}
İletişim kutusunun stilini belirleme <footer>
Altbilginin rolü, işlem düğmelerinin menüleri içermesidir. Flexbox, Flexbox'ın kullanıldığı içeriği altbilgi satır içi ekseninin sonuna hizalayın ve daha sonra, düğmelere biraz alan tanıyın.
dialog > form > footer {
background: var(--surface-2);
display: flex;
flex-wrap: wrap;
gap: var(--size-3);
justify-content: space-between;
align-items: flex-start;
padding-inline: var(--size-5);
padding-block: var(--size-3);
}
@media (prefers-color-scheme: dark) {
dialog > form > footer {
background: var(--surface-1);
}
}
İletişim kutusu altbilgi menüsünün stilini belirleme
menu
öğesi, iletişim kutusuna ilişkin işlem düğmelerini içermek için kullanılır. Sarmalama kullanır
Düğmeler arasında boşluk sağlamak için gap
ile flexbox düzeni. Menü öğeleri
<ul>
gibi bir dolgu içerir. Ayrıca, ihtiyacım olmadığı için bu stili kaldırıyorum.
dialog > form > footer > menu {
display: flex;
flex-wrap: wrap;
gap: var(--size-3);
padding-inline-start: 0;
}
dialog > form > footer > menu:only-child {
margin-inline-start: auto;
}
Animasyon
İletişim kutusu öğeleri, pencereye girip çıktıkları için genellikle canlandırmalı olur. Diyaloglara bu giriş ve çıkış için destekleyici hareketler sunmak kullanıcıların odaklanmasını sağlamak.
Normalde iletişim kutusu öğesi yalnızca animasyon içine eklenebilir, dışarı çıkarılamaz. Çünkü
tarayıcı, öğedeki display
özelliğini açar. Önceki videolarda, kılavuz
ekranı ızgaraya ayarlayın ve hiçbir zaman "yok" olarak ayarlama. Bu sayede,
ekibinizle beraber
animasyon içerir.
Open Props oyunlarının birçok animasyon karesi animasyonların kullanılmasını sağlayın; ve okunaklı hale getirebilirsiniz. Burada animasyon hedefleri ve katmanlı şu yaklaşımı benimsedim:
- Azaltılmış hareket, varsayılan geçiştir. Basit bir opaklık giderek azalır.
- Hareket yeterliyse kaydırma ve ölçek animasyonları eklenir.
- Mega iletişim için duyarlı mobil düzen, dışarı kayacak şekilde ayarlandı.
Güvenli ve anlamlı bir varsayılan geçiş
Open Props ekran görüntüsünde azalan ve dönüşler için animasyon kareleri bulunsa da bunu
katmanlı geçiş yaklaşımını kullanarak varsayılan olarak animasyon karesi
gerçekleşebilir. Daha önceki videolarda diyaloğun görünürlüğünü
opaklık, [open]
özelliğine bağlı olarak 1
veya 0
düzenlenir. Alıcı:
%0 ve %100 arasında bir geçiş olursa, tarayıcıya ne kadar ve ne tür
istediğiniz yumuşatmayı tercih edebilirsiniz:
dialog {
transition: opacity .5s var(--ease-3);
}
Geçişe hareket ekleme
Kullanıcı hareketi kabul ediyorsa hem mega hem de mini iletişim kutuları kaymalıdır
izin verilir ve çıkış olarak ölçeklendirilir. Bunu başarmak için
prefers-reduced-motion
medya sorgusu ve birkaç Open Prop:
@media (prefers-reduced-motion: no-preference) {
dialog {
animation: var(--animation-scale-down) forwards;
animation-timing-function: var(--ease-squish-3);
}
dialog[open] {
animation: var(--animation-slide-in-up) forwards;
}
}
Çıkış animasyonunu mobil cihazlar için uyarlama
Stil bölümünün başlarında mega diyalog stili, mobil cihazlar için sanki küçük bir kağıt parçasının kaydığı gibi bir işlem sayfasına ekranın alt kısmından yukarı bakıyor ve hâlâ alta sabitlenmiş durumda. Ölçek çıkış animasyonu, bu yeni tasarıma iyi uymamaktadır ve bunu, bazı medya sorguları ve bazı Open Prop'ler:
@media (prefers-reduced-motion: no-preference) and @media (max-width: 768px) {
dialog[modal-mode="mega"] {
animation: var(--animation-slide-out-down) forwards;
animation-timing-function: var(--ease-squish-2);
}
}
JavaScript
JavaScript'e eklenecek pek çok şey vardır:
// dialog.js
export default async function (dialog) {
// add light dismiss
// add closing and closed events
// add opening and opened events
// add removed event
// removing loading attribute
}
Bu eklemeler, ışığın kapatılması (iletişim kutusunu arka plan), animasyonu ve diğer etkinlikleri içeren olduğunu unutmayın.
Işık kapatma ekleniyor
Bu görev basittir ve gözünüzden kaçan bir diyalog öğesine
animasyon kullanılır. Etkileşim, iletişim kutusundaki tıklamaların izlenmesiyle gerçekleştirilir
öğesi oluşturmak için bir etkinlik
şampuan
yalnızca neyin tıklandığını değerlendirecek ve
close()
en üstteki öğe ise:
export default async function (dialog) {
dialog.addEventListener('click', lightDismiss)
}
const lightDismiss = ({target:dialog}) => {
if (dialog.nodeName === 'DIALOG')
dialog.close('dismiss')
}
Uyarı dialog.close('dismiss')
. Etkinlik çağrılır ve bir dize sağlanır.
Bu dize,
iletişim kutusu kapatıldı. Her telefon ettiğimde de kapattığım dizeleri
çeşitli düğmelerden işlevini kullanarak, uygulamama
kullanıcı etkileşimi.
Kapanış ve kapanış etkinlikleri ekleme
İletişim öğesi bir kapatma etkinliğiyle gelir:
iletişim kutusu close()
işlevi çağrılır. Bu öğeyi canlandırdığımız için
animasyondan önce ve sonra
etkinlikler olması güzel.
veya iletişim formunu sıfırlayın. Burada,
Kapatılan iletişim kutusunda inert
özelliği var ve demoda bunu değiştirmek için
Kullanıcı yeni bir resim gönderdiğinde avatar listesine eklenir.
Bunu elde etmek için closing
ve closed
adında iki yeni etkinlik oluşturun. Sonra
yerleşik kapatma etkinliğini dinleyin. Buradan iletişim kutusunu
inert
ve closing
etkinliğini gönderin. Bir sonraki görev,
animasyonların ve geçişlerin iletişim kutusunda çalışmasını bitirmek, ardından
closed
etkinliği.
const dialogClosingEvent = new Event('closing')
const dialogClosedEvent = new Event('closed')
export default async function (dialog) {
…
dialog.addEventListener('close', dialogClose)
}
const dialogClose = async ({target:dialog}) => {
dialog.setAttribute('inert', '')
dialog.dispatchEvent(dialogClosingEvent)
await animationsComplete(dialog)
dialog.dispatchEvent(dialogClosedEvent)
}
const animationsComplete = element =>
Promise.allSettled(
element.getAnimations().map(animation =>
animation.finished))
Kısa mesaj oluşturma bölümünde de kullanılan animationsComplete
işlevi
bileşenine göre bir vaat döndürür.
animasyon ve geçiş taahhütlerinin tamamlanmasına yardımcı olun. Bu nedenle dialogClose
eş zamansızdır
fonksiyon;
o zaman
await
ve emin adımlarla kapalı etkinliğe
devam etmek ister misiniz?
Açılış ve açık etkinlikler ekleme
Yerleşik iletişim öğesi kolayca eklenemeyeceği için bu etkinlikleri eklemek tıpkı kapanışta olduğu gibi açık bir etkinlik sağlar. Ben MutationObserver seçerek iletişim kutusunun özellikleriyle ilgili anlamlı analizler elde edebilirsiniz. Bu gözlemcide Açık özellikteki değişiklikleri gözlemleyip özel etkinlikleri yöneteceğim buna göre hazırlar.
Kapanış ve kapanış etkinliklerimize benzer şekilde iki yeni etkinlik oluşturun.
opening
ve opened
. Daha önce diyaloğun kapatılmasını dinlediğimiz platform
Bu kez, diyalogun durumunu izlemek için oluşturulmuş bir mutasyon gözlemleyicisi
özellikleri hakkında daha fazla bilgi edinin.
…
const dialogOpeningEvent = new Event('opening')
const dialogOpenedEvent = new Event('opened')
export default async function (dialog) {
…
dialogAttrObserver.observe(dialog, {
attributes: true,
})
}
const dialogAttrObserver = new MutationObserver((mutations, observer) => {
mutations.forEach(async mutation => {
if (mutation.attributeName === 'open') {
const dialog = mutation.target
const isOpen = dialog.hasAttribute('open')
if (!isOpen) return
dialog.removeAttribute('inert')
// set focus
const focusTarget = dialog.querySelector('[autofocus]')
focusTarget
? focusTarget.focus()
: dialog.querySelector('button').focus()
dialog.dispatchEvent(dialogOpeningEvent)
await animationsComplete(dialog)
dialog.dispatchEvent(dialogOpenedEvent)
}
})
})
İletişim kutusu görüntülendiğinde mutasyon gözlemleyicisi geri çağırma işlevi
özellikleri değiştirilir ve değişikliklerin listesi bir dizi olarak gösterilir. Yineleme yap
özellik değişir ve attributeName
öğesinin açık olup olmadığına bakar. Ardından,
öğenin özelliğe sahip olup olmadığı bilgisi: Bu, iletişim kutusunun
hale gelmiştir. Açılmışsa inert
özelliğini kaldırın, odağı ayarlayın
başka bir öğeden birine
autofocus
veya iletişim kutusundaki ilk button
öğesi. Son olarak,
ve kapalı etkinlik varsa, açılış etkinliğini hemen gönderin, animasyonların gelmesini bekleyin
ve açılan etkinliği gönderin.
Kaldırılan bir etkinliği ekleme
Tek sayfalık uygulamalarda, iletişim kutuları genellikle rotalara göre eklenip kaldırılır beyanda bulunmanız gerekir. Bu araç, etkinlikleri temizlemek veya verilerini de görebilirsiniz.
Bunu başka bir mutasyon gözlemcisiyle başarabilirsiniz. Bu sefer, özellikleri gözlemlediğimizde, vücudun alt öğelerini gözlemleyeceğiz öğesine dokunun ve iletişim kutusu öğelerinin kaldırılmasını bekleyin.
…
const dialogRemovedEvent = new Event('removed')
export default async function (dialog) {
…
dialogDeleteObserver.observe(document.body, {
attributes: false,
subtree: false,
childList: true,
})
}
const dialogDeleteObserver = new MutationObserver((mutations, observer) => {
mutations.forEach(mutation => {
mutation.removedNodes.forEach(removedNode => {
if (removedNode.nodeName === 'DIALOG') {
removedNode.removeEventListener('click', lightDismiss)
removedNode.removeEventListener('close', dialogClose)
removedNode.dispatchEvent(dialogRemovedEvent)
}
})
})
})
Alt öğeler eklendiğinde veya kaldırıldığında mutasyon gözlemleyici geri çağırması çağrılır
. İzlenen belirli mutasyonlar
Şuna sahip removedNodes
:
nodeName
/
iletişim kutusu. İletişim kutusu kaldırıldıysa tıklama ve kapatma etkinlikleri
yer açın ve kaldırılan özel etkinlik gönderilir.
Yükleme özelliği kaldırılıyor
İletişim kutusu animasyonunun iletişim kutusuna bir yükleme özelliği eklenmiştir. İlgili içeriği oluşturmak için kullanılan aşağıdaki komut dosyası, iletişim kutusu animasyonlarının çalışmasının bitmesini bekler ve belirtir. Artık diyaloğun içindeki animasyonlar serbestçe açılabilir. Ayrıca, başka türlü dikkat dağıtan bir animasyonu etkili şekilde gizlemiştir.
export default async function (dialog) {
…
await animationsComplete(dialog)
dialog.removeAttribute('loading')
}
Sayfa yüklemede animasyon karesi animasyonlarını engelleme sorunu hakkında daha fazla bilgi edinin. burada bulabilirsiniz.
Hepsi bir arada
Her bölümü açıkladığımıza göre dialog.js
buradan
ayrı ayrı:
// custom events to be added to <dialog>
const dialogClosingEvent = new Event('closing')
const dialogClosedEvent = new Event('closed')
const dialogOpeningEvent = new Event('opening')
const dialogOpenedEvent = new Event('opened')
const dialogRemovedEvent = new Event('removed')
// track opening
const dialogAttrObserver = new MutationObserver((mutations, observer) => {
mutations.forEach(async mutation => {
if (mutation.attributeName === 'open') {
const dialog = mutation.target
const isOpen = dialog.hasAttribute('open')
if (!isOpen) return
dialog.removeAttribute('inert')
// set focus
const focusTarget = dialog.querySelector('[autofocus]')
focusTarget
? focusTarget.focus()
: dialog.querySelector('button').focus()
dialog.dispatchEvent(dialogOpeningEvent)
await animationsComplete(dialog)
dialog.dispatchEvent(dialogOpenedEvent)
}
})
})
// track deletion
const dialogDeleteObserver = new MutationObserver((mutations, observer) => {
mutations.forEach(mutation => {
mutation.removedNodes.forEach(removedNode => {
if (removedNode.nodeName === 'DIALOG') {
removedNode.removeEventListener('click', lightDismiss)
removedNode.removeEventListener('close', dialogClose)
removedNode.dispatchEvent(dialogRemovedEvent)
}
})
})
})
// wait for all dialog animations to complete their promises
const animationsComplete = element =>
Promise.allSettled(
element.getAnimations().map(animation =>
animation.finished))
// click outside the dialog handler
const lightDismiss = ({target:dialog}) => {
if (dialog.nodeName === 'DIALOG')
dialog.close('dismiss')
}
const dialogClose = async ({target:dialog}) => {
dialog.setAttribute('inert', '')
dialog.dispatchEvent(dialogClosingEvent)
await animationsComplete(dialog)
dialog.dispatchEvent(dialogClosedEvent)
}
// page load dialogs setup
export default async function (dialog) {
dialog.addEventListener('click', lightDismiss)
dialog.addEventListener('close', dialogClose)
dialogAttrObserver.observe(dialog, {
attributes: true,
})
dialogDeleteObserver.observe(document.body, {
attributes: false,
subtree: false,
childList: true,
})
// remove loading attribute
// prevent page load @keyframes playing
await animationsComplete(dialog)
dialog.removeAttribute('loading')
}
dialog.js
modülünü kullanma
Modülden dışa aktarılan işlevin bir iletişim kutusu çağrılmasını ve iletilmesini bekler öğesi ekleyin:
import GuiDialog from './dialog.js'
const MegaDialog = document.querySelector('#MegaDialog')
const MiniDialog = document.querySelector('#MiniDialog')
GuiDialog(MegaDialog)
GuiDialog(MiniDialog)
Aynı şekilde iki iletişim kutusu da ışık kapatma, animasyon ve daha fazla etkinlikle ilgili bilgi sahibi olabilirsiniz.
Yeni özel etkinlikleri dinleme
Yükseltilen her iletişim öğesi artık aşağıdaki gibi beş yeni etkinliği dinleyebilir:
MegaDialog.addEventListener('closing', dialogClosing)
MegaDialog.addEventListener('closed', dialogClosed)
MegaDialog.addEventListener('opening', dialogOpening)
MegaDialog.addEventListener('opened', dialogOpened)
MegaDialog.addEventListener('removed', dialogRemoved)
Aşağıda, bu etkinliklerin işlenmesiyle ilgili iki örnek verilmiştir:
const dialogOpening = ({target:dialog}) => {
console.log('Dialog opening', dialog)
}
const dialogClosed = ({target:dialog}) => {
console.log('Dialog closed', dialog)
console.info('Dialog user action:', dialog.returnValue)
if (dialog.returnValue === 'confirm') {
// do stuff with the form values
const dialogFormData = new FormData(dialog.querySelector('form'))
console.info('Dialog form data', Object.fromEntries(dialogFormData.entries()))
// then reset the form
dialog.querySelector('form')?.reset()
}
}
İletişim öğesiyle oluşturduğum demoda bu kapalı etkinliği kullanıp form verilerini tıklayarak listeye yeni bir avatar öğesi ekleyin. Zamanlamanın iyi olması iletişim kutusunun çıkış animasyonunu tamamladığını ve ardından bazı komut dosyalarının animasyon simgesini tıklayın. Yeni etkinlikler sayesinde kullanıcı deneyimini düzenlemek olabilir.
dialog.returnValue
dikkati: Bu kod,
close()
iletişim kutusu çağrıldı. dialogClosed
etkinliğinde çok önemli olan
iletişimin kapatılıp kapatılmadığını, iptal edilip edilmediğini veya onaylanıp onaylanmadığını öğrenebilirsiniz. Onaylanırsa
komut dosyası, form değerlerini alıp formu sıfırlar. Sıfırlama işlemi,
iletişim kutusu tekrar gösterildiğinde boş ve yeni gönderim için hazırdır.
Sonuç
Şimdi bunu nasıl yaptığımı öğrendiğinize göre siz nasıl ‽ 🙂
Gelin, yaklaşımlarımızı çeşitlendirelim ve web'de içerik geliştirmenin tüm yollarını öğrenelim.
Bir demo oluşturup beni tweet'le bağlantıları eklerim aşağıdaki topluluk remiksleri bölümüne gidin!
Topluluk remiksleri
- @GrimLink ve 3'ü 1 Arada iletişim kutusu.
- @mikemai2awesome ile güzel bir
değiştirmenin
display
mülkü. - @geoffrich_ Şık ve hoş İnce bir FLIP parlaklığı.
Kaynaklar
- GitHub'da kaynak kodu
- Doodle avatarları