نظرة عامة أساسية حول كيفية إنشاء مكوِّن إشعار منبثق تكيّفي يمكن الوصول إليه.
أود في هذه المقالة أن أشارككم بالتفكير في كيفية إنشاء مكون الخبز المحمص. ندعوك لبدء العرض التوضيحي.
إليك نسخة من هذه المشاركة على 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 استعلام الوسائط المفضل.
.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()
طريقة التعامل مع واحد.
أو الكثير من الخبز المحمص. تحقق أولاً من عدد محمصات الخبز، وما إذا كانت الحركة لا بأس بها،
ثم استخدام هذه المعلومات لإلحاق الخبز المحمص أو تنفيذ بعض الأفكار
رسوم متحركة حتى تظهر الإشعارات الأخرى وكأنها "توفير مساحة" لنخب جديد.
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()
عند وجود نخب موجود، وذلك باستخدام تقنية
يسمى FLIP من قبل بول
"لويس" تكمن الفكرة في حساب الفرق
في مواضع الحاوية، قبل إضافة الإشعار المنبثق الجديد وبعده.
فكر في الأمر مثل وضع علامة على مكان محمصة الخبز الآن، وأين ستكون، ثم
المتحركة من مكانها إلى مكانها.
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()
يفي بوعد "توست" عالي المستوى
يمكن للمطوّرين حذف البيانات أو إجراء أي عمل آخر بمجرد أن يظهر الإشعار المنبثق.
export default Toast
وأخيرًا، يتم تصدير الدالة Toast
من الوحدة، بالنسبة إلى النصوص البرمجية الأخرى إلى
البيانات واستخدامها.
استخدام مكون Toast
يتم استخدام الخبز المحمص، أو تجربة مطور الخبز، عن طريق استيراد
Toast
وتسميها باستخدام سلسلة رسالة.
import Toast from './toast.js'
Toast('Wizard Rose added to cart')
إذا أراد المطور القيام بأي عمل تنظيف أو أي شيء، بعد أن تظهر، فيمكنها استخدام البيانات غير المتزامنة الانتظار.
import Toast from './toast.js'
async function example() {
await Toast('Wizard Rose added to cart')
console.log('toast finished')
}
الخاتمة
الآن بعد أن تعرّفت على كيفية إجراء ذلك، كيف يمكنك‽ 🙂
يمكننا تنويع أساليبنا وتعلُّم جميع طرق إنشاء المحتوى على الويب. أنشئ عرضًا توضيحيًا وأضيف روابط تغريدة إليّ. انتقِل إلى قسم الريمكسات في المنتدى أدناه.
ريمكسات من إنشاء المنتدى
- @_developit مع HTML/CSS/JS: demo & الرمز
- Joost van der Schee مع HTML/CSS/JS: demo & الرمز