ภาพรวมพื้นฐานของวิธีสร้างคอมโพเนนต์โทสต์แบบปรับเปลี่ยนได้และเข้าถึงง่าย
ในโพสต์นี้ผมอยากจะแชร์วิธีคิดวิธีสร้างคอมโพเนนต์ข้อความโทสต์ ทดลองใช้ การสาธิต
หากต้องการดูวิดีโอ โปรดใช้โพสต์นี้ในเวอร์ชัน 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>
ภาชนะใส่ข้อความโทสต์
แสดงข้อความโทสต์ได้มากกว่า 1 รายการต่อครั้ง เพื่อจัดการเป็นกลุ่ม ข้อความโทสต์ ระบบจะใช้ภาชนะบรรจุ คอนเทนเนอร์นี้ยังจัดการตำแหน่งของ ข้อความโทสต์บนหน้าจอ
<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
ของวิวพอร์ต และหากมีการเพิ่มข้อความโทสต์ ข้อความจะซ้อนมาจากขอบหน้าจอนั้น
คอนเทนเนอร์ GUI
คอนเทนเนอร์โทสต์ทำงานเลย์เอาต์ทุกอย่างสำหรับการนำเสนอข้อความโทสต์ ตอนนี้
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;
}
ข้อความโทสต์ GUI
ขนมปังปิ้งแต่ละชิ้นมี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;
}
ข้อความโทสต์ GUI
ปรับธีมโทสต์ให้เหมาะกับสีอ่อนหรือสีเข้มพร้อมคุณสมบัติที่กำหนดเอง รวมถึง 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%;
}
}
แอนิเมชัน
ข้อความโทสต์ใหม่ควรแสดงตัวเองด้วยภาพเคลื่อนไหวขณะที่ข้อความโทสต์เข้าสู่หน้าจอ
รองรับการเคลื่อนไหวที่ลดลงโดยกำหนดค่า 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')
การสร้างกลุ่มข้อความโทสต์และขนมปังปิ้ง
เมื่อโมดูลข้อความโทสต์โหลดจาก JavaScript ก็จะต้องสร้างคอนเทนเนอร์โทสต์
แล้วเพิ่มลงในหน้าเว็บ ฉันเลือกเพิ่มองค์ประกอบก่อน 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
}
การจัดการข้อความโทสต์อย่างน้อย 1 รายการ
ตอนนี้ JavaScript จะเพิ่มคอนเทนเนอร์ลงในเอกสาร เพื่อให้มีข้อความโทสต์และ
พร้อมที่จะเพิ่มข้อความโทสต์ที่สร้างขึ้นแล้ว ฟังก์ชัน addToast()
จัดการ 1
หรือขนมปังปิ้งหลายชิ้น ก่อนอื่น การตรวจสอบจำนวนข้อความโทสต์และดูว่าการเคลื่อนไหวเหมาะสมหรือไม่
แล้วใช้ข้อมูลนี้เพื่อนำไปต่อท้ายข้อความโทสต์
หรือแต่งให้ดูดี
ภาพเคลื่อนไหวเพื่อให้ข้อความโทสต์อื่นๆ ปรากฏขึ้นเพื่อ "เพิ่มพื้นที่ว่าง" สำหรับขนมปังปิ้งใหม่
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 โดย Paul
Lewis แนวคิดก็คือ การคำนวณผลต่าง
ในตำแหน่งต่างๆ ของคอนเทนเนอร์ ก่อนและหลังเพิ่มโทสต์ใหม่
เปรียบได้กับการทำเครื่องหมายตำแหน่งของ Toaster ในปัจจุบัน ตำแหน่งของมัน จากนั้น
ภาพเคลื่อนไหวจากจุดหนึ่งไปยังอีกจุดหนึ่ง
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 ที่เสร็จสมบูรณ์ (ภาพเคลื่อนไหว 3 คีย์เฟรม) สำหรับการแก้ปัญหาตามที่สัญญาไว้
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
และเรียกใช้ด้วยสตริงข้อความ
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: การสาธิตและ รหัส
- Joost van der Schee กับ HTML/CSS/JS: การสาธิตและ รหัส