نظرة عامة أساسية حول كيفية إنشاء مكوّن مربّع حوار منبثق قابل للتكيّف وسهل الاستخدام
في هذه المشاركة، أريد مشاركة أفكار حول كيفية إنشاء مكوّن مربّع حوار منبثق. جرِّب الإصدار التجريبي.
إذا كنت تفضّل الفيديو، يمكنك الاطّلاع على نسخة من هذه المشاركة على YouTube:
نظرة عامة
النوافذ المنبثقة هي رسائل قصيرة غير تفاعلية وغير متزامنة للمستخدمين. ويتم استخدامها بشكل عام كنمط لملاحظات الواجهة لإعلام المستخدم بنتائج إجراء معيّن.
التفاعلات
تختلف الإشعارات المنبثقة عن الإشعارات والتنبيهات و الطلبات لأنّه لا يمكن التفاعل معها، وليس من المفترض إغلاقها أو إبقاؤها ظاهرة. وتهدف الإشعارات إلى عرض معلومات أكثر أهمية أو رسائل متزامنة تتطلب التفاعل، أو لإرسال رسائل على مستوى النظام (بدلاً من إرسال رسائل على مستوى الصفحة). تكون الإشعارات المنبثقة أكثر استسلامًا من استراتيجيات الإشعارات الأخرى.
Markup
يُعدّ عنصر
<output>
خيارًا جيدًا لخبز الخبز لأنّه يتم تعريفه لبرامج قراءة الشاشة. توفّر لغة HTML الصحيحة قاعدة آمنة يمكننا تحسينها باستخدام JavaScript و
CSS، وسيكون هناك الكثير من JavaScript.
نخب
<output class="gui-toast">Item added to cart</output>
يمكن أن يكون أكثر
شمولاً
من خلال إضافة role="status"
. يقدّم ذلك بديلاً في حال عدم منح المتصفّح عناصر <output>
دورًا
ضمنيًا
وفقًا للمواصفات.
<output role="status" class="gui-toast">Item added to cart</output>
حاوية الخبز
يمكن عرض أكثر من إشعار عائم في الوقت نفسه. لتنظيم عدة خبز محمص، يتم استخدام حاوية. تتحكّم هذه الحاوية أيضًا في موضع الرسائل المنبثقة على الشاشة.
<section class="gui-toast-group">
<output role="status">Wizard Rose added to cart</output>
<output role="status">Self Watering Pot added to cart</output>
</section>
التنسيقات
اخترت تثبيت الإشعارات المنبثقة في
inset-block-end
مساحة العرض، وفي حال إضافة المزيد من الإشعارات المنبثقة، يتم تجميعها من تلك الحافة على الشاشة.
حاوية واجهة المستخدم الرسومية
تقوم حاوية الخبز بجميع أعمال التخطيط لتقديم الخبز المحمص. وهي تُستخدم fixed
في إطار العرض وتستخدم السمة المنطقية inset
لتحديد الحواف التي يجب التثبيت عليها، بالإضافة إلى جزء صغير من padding
من حافة block-end
نفسها.
.gui-toast-group {
position: fixed;
z-index: 1;
inset-block-end: 0;
inset-inline: 0;
padding-block-end: 5vh;
}
بالإضافة إلى تحديد موضع حاوية مربّع المعلومات المنبثق في إطار العرض، تكون حاوية مربّع المعلومات المنبثق
حاوية شبكة يمكنها محاذاة مربّعات المعلومات المنبثقة وتوزيعها. يتمّ وضع العناصر في وسط الشاشة كمجموعة باستخدام justify-content
وفي وسط الشاشة بشكلٍ فردي باستخدام justify-items
.
يُرجى رمي gap
قليلاً حتى لا تلمس رسائل الخبز المحمص.
.gui-toast-group {
display: grid;
justify-items: center;
justify-content: center;
gap: 1vh;
}
واجهة المستخدم الرسومية الجديدة
يتضمّن خبز محمص فردي بعض padding
، وبعض الزوايا الأخف من خلال علامة
border-radius
،
ووظيفة min()
للمساعدة في
تحديد حجم المحتوى على الأجهزة الجوّالة وأجهزة الكمبيوتر المكتبي. يمنع الحجم المتوافق مع جميع الأجهزة في ملف CSS التالي
تضخّم النوافذ المنبثقة إلى أكثر من %90 من إطار العرض أو
25ch
.
.gui-toast {
max-inline-size: min(25ch, 90vw);
padding-block: .5ch;
padding-inline: 1ch;
border-radius: 3px;
font-size: 1rem;
}
الأنماط
بعد ضبط التنسيق والموضع، أضِف ملف CSS يساعد في التكيّف مع إعدادات المستخدم وتفاعلاته.
حاوية الخبز
لا تكون الإشعارات المنبثقة تفاعلية، ولا يؤدي النقر عليها أو التمرير السريع عليها إلى أي إجراء، ولكنها تستهلك حاليًا أحداث المؤشر. امنع الإشعارات المبسّطة من سرقة النقرات باستخدام خدمة مقارنة الأسعار (CSS) التالية.
.gui-toast-group {
pointer-events: none;
}
إشعار منبثق لواجهة المستخدم الرسومية
يمكنك منح الإشعارات المنبثقة مظهرًا متوافقًا فاتحًا أو داكنًا باستخدام خصائص مخصّصة ونظام الألوان HSL و query media preference.
.gui-toast {
--_bg-lightness: 90%;
color: black;
background: hsl(0 0% var(--_bg-lightness) / 90%);
}
@media (prefers-color-scheme: dark) {
.gui-toast {
color: white;
--_bg-lightness: 20%;
}
}
Animation
يجب أن يقدم إشعار منبثق جديد نفسه مع صورة متحركة عند دخوله إلى الشاشة.
يتم تنفيذ عملية تقليل الحركة من خلال ضبط قيم translate
على 0
بشكل تلقائي، ولكن مع تعديل قيمة الحركة إلى طول في طلب بحث الوسائط المفضّلة للحركة . يظهر للجميع بعض الصور المتحركة، ولكن يظهر للبعض فقط مربّع الرسالة المنبثقة وهو يتحرك.
في ما يلي الإطارات الرئيسية المستخدَمة في الصورة المتحركة للشريط المنبثق. ستتحكم CSS في مدخل، والانتظار، والخروج من الخبز المحمص، كل ذلك في رسم متحرك واحد.
@keyframes fade-in {
from { opacity: 0 }
}
@keyframes fade-out {
to { opacity: 0 }
}
@keyframes slide-in {
from { transform: translateY(var(--_travel-distance, 10px)) }
}
بعد ذلك، يُعدّ عنصر مربّع الرسائل المنبثقة المتغيّرات وينظّم الإطارات الرئيسية.
.gui-toast {
--_duration: 3s;
--_travel-distance: 0;
will-change: transform;
animation:
fade-in .3s ease,
slide-in .3s ease,
fade-out .3s ease var(--_duration);
}
@media (prefers-reduced-motion: no-preference) {
.gui-toast {
--_travel-distance: 5vh;
}
}
JavaScript
عندما تكون الأنماط وتنسيقات HTML التي يمكن الوصول إليها باستخدام قارئ الشاشة جاهزة، ستكون هناك حاجة إلى JavaScript لتنظيم عملية إنشاء الإشعارات المحمصة وإضافتها وإتلافها استنادًا إلى أحداث المستخدم. يجب أن تكون تجربة المطوّر لمكوّن مربّع الرسائل المنبثقة بسيطة وسهلة البدء، على النحو التالي:
import Toast from './toast.js'
Toast('My first toast')
إنشاء مجموعة الإشعارات المنبثقة والإشعارات المنبثقة
عند تحميل وحدة Toast من JavaScript، يجب أن تنشئ حاوية toast وتضيفها إلى الصفحة. اخترت إضافة العنصر قبل body
، ما سيقلّل من احتمال حدوث مشاكل في تجميع
z-index
لأنّ الحاوية فوق الحاوية التي تحتوي على
جميع عناصر النصّ.
const init = () => {
const node = document.createElement('section')
node.classList.add('gui-toast-group')
document.firstElementChild.insertBefore(node, document.body)
return node
}
يتم استدعاء الدالة init()
داخليًا في الوحدة، مع تخزين العنصر كـ Toaster
:
const Toaster = init()
يتم إنشاء عنصر HTML للشريط المنبثق باستخدام الدالة createToast()
. تتطلّب الدالة بعض النصوص، وتنشئ عنصر <output>
وتزيّنه ببعض الفئات والسمات، وتضبط النص، وتعرض العقدة.
const createToast = text => {
const node = document.createElement('output')
node.innerText = text
node.classList.add('gui-toast')
node.setAttribute('role', 'status')
return node
}
إدارة إشعار منبثق واحد أو عدّة إشعارات
تضيف JavaScript الآن حاوية إلى المستند لاحتواء الإشعارات المنبثقة وتكون
جاهزة لإضافة الإشعارات المنبثقة التي تم إنشاؤها. تنظِّم الدالة addToast()
معالجة رسائل Toast واحدة
أو عدّة رسائل. تحقق أولاً من عدد محمصات الخبز، وما إذا كانت الحركة لا بأس بها،
ثم استخدم هذه المعلومات لإلحاق الخبز المحمص أو لإضافة بعض الرسوم المتحركة
التخيلية بحيث تبدو الإعلانات الأخرى "لتوفير مساحة" للخبز المحمص الجديد.
const addToast = toast => {
const { matches:motionOK } = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Toaster.children.length && motionOK
? flipToast(toast)
: Toaster.appendChild(toast)
}
عند إضافة أول رسالة مصغّرة، يضيف Toaster.appendChild(toast)
رسالة مصغّرة إلى
الصفحة التي تشغّل صور CSS المتحركة: عرض الصورة المتحركة، الانتظار 3s
، إخفاء الصورة المتحركة.
يتمّ استدعاء flipToast()
عندما تكون هناك إشعارات Toast حالية، باستخدام أسلوب
يُسمّى FLIP من قِبل Paul
Lewis. والفكرة هي احتساب الفرق
في مواضع الحاوية قبل إضافة النافذة المنبثقة الجديدة وبعدها.
يمكنك اعتبار ذلك مثل وضع علامة على مكان "محمّصة الخبز" الآن، ومكانها القادم، ثم
إضافة مؤثرات متحركة من مكانها السابق إلى مكانها الحالي.
const flipToast = toast => {
// FIRST
const first = Toaster.offsetHeight
// add new child to change container size
Toaster.appendChild(toast)
// LAST
const last = Toaster.offsetHeight
// INVERT
const invert = last - first
// PLAY
const animation = Toaster.animate([
{ transform: `translateY(${invert}px)` },
{ transform: 'translateY(0)' }
], {
duration: 150,
easing: 'ease-out',
})
}
تُستخدم شبكة CSS لرفع التخطيط. عند إضافة إشعار عاجل جديد، تضعه الشبكة في البداية وتترك مسافة بينه وبين الإشعارات الأخرى. وفي الوقت نفسه، يتم استخدام تأثير متحرك على الويب لتحريك الحاوية من موضعها القديم.
تجميع كل رمز JavaScript معًا
عند استدعاء Toast('my first toast')
، يتم إنشاء إشعار منبثق تتم إضافته إلى الصفحة
(ربما تكون الحاوية متحركة لتلائم النموذج الجديد)، ويتم عرض وعد
تتم مراقبة اكتمال الصور المتحركة لـ CSS (الرسوم المتحركة الثلاثة للإطارات الرئيسية) للحصول على حل للوعود.
const Toast = text => {
let toast = createToast(text)
addToast(toast)
return new Promise(async (resolve, reject) => {
await Promise.allSettled(
toast.getAnimations().map(animation =>
animation.finished
)
)
Toaster.removeChild(toast)
resolve()
})
}
أعتقد أنّ الجزء المربك في هذا الرمز هو وظيفة Promise.allSettled()
وتعيين toast.getAnimations()
. بما أنّني استخدمت عدّة صور متحرّكة للإطارات الرئيسية
لشريط الإشعارات المنبثقة، لمعرفة ما إذا كانت قد اكتملت جميعها، يجب أن تتم أولاً
طلب كل منها من JavaScript، ثم يجب مراقبة كل من
finished
الوعد الذي يُقدّمه كل منها لإكماله.
allSettled
يناسبنا ذلك، حيث يتم حلّ المشكلة تلقائيًا بعد تنفيذ كل الوعود التي تقدّمها
. يعني استخدام await Promise.allSettled()
أنّ السطر التالي من
الرمز البرمجي يمكنه إزالة العنصر بثقة وافتراض أنّ النافذة المنبثقة قد أكملت
دورة حياتها. وأخيرًا، يفي الاتصال بـ resolve()
الوعد باستخدام Toast عالي المستوى بحيث
يمكن للمطوّرين تنظيف أو القيام بأي عمل آخر بعد ظهور الإشعار المنبثق.
export default Toast
أخيرًا، يتم تصدير الدالة Toast
من الوحدة لنصوص برمجية أخرى تتمكّن من
استيرادها واستخدامها.
استخدام مكوّن Toast
يتم استخدام النموذج المنبثق أو تجربة مطوّر التطبيق من خلال استيراد دالة Toast
وطلبها باستخدام سلسلة رسالة.
import Toast from './toast.js'
Toast('Wizard Rose added to cart')
إذا أراد المطوّر إجراء عملية تنظيف أو أيّ إجراء آخر، يمكنه استخدام async وawait بعد عرض مربّع التلميح.
import Toast from './toast.js'
async function example() {
await Toast('Wizard Rose added to cart')
console.log('toast finished')
}
الخاتمة
الآن بعد أن عرفت كيف فعلت ذلك، كيف ستفعل ذلك؟ 🙂
لننوّع أساليبنا ونتعرّف على جميع الطرق لإنشاء تطبيقات على الويب. أنشئ عرضًا توضيحيًا أو روابط تغريدةني وسأضيفه إلى قسم الريمكسات في المنتدى أدناه.
الريمكسات التي أنشأها المستخدمون
- @_developit باستخدام HTML/CSS/JS: الإصدار التجريبي والرمز البرمجي
- Joost van der Schee باستخدام HTML/CSS/JS: العرض الترويجي والرمز البرمجي