การสร้างคอมโพเนนต์ของแถบการโหลด

ภาพรวมพื้นฐานของวิธีสร้างแถบโหลดที่ปรับเปลี่ยนได้และเข้าถึงง่ายด้วยองค์ประกอบ <progress>

ในโพสต์นี้ ผมจะมาแชร์แนวคิดเกี่ยวกับวิธีสร้างแถบการโหลดที่ปรับแต่งได้และ เข้าถึงได้ง่ายโดยใช้องค์ประกอบ <progress> ลองดูการสาธิตและดูแหล่งที่มา

สาธิตแบบสว่างและมืด ไม่ชัด เพิ่มขึ้น และเสร็จสมบูรณ์ใน Chrome

หากชอบวิดีโอ นี่คือโพสต์นี้เวอร์ชัน YouTube

ภาพรวม

องค์ประกอบ <progress> จะแสดงฟีดแบ็กที่เป็นภาพและเสียงแก่ผู้ใช้เกี่ยวกับความสำเร็จ ความคิดเห็นที่เป็นภาพนี้มีประโยชน์ต่อสถานการณ์ต่างๆ เช่น ความคืบหน้าผ่านแบบฟอร์ม การแสดงการดาวน์โหลดหรืออัปโหลดข้อมูล หรือแม้กระทั่งการแสดงว่าไม่ทราบปริมาณความคืบหน้าแต่ยังดำเนินการอยู่

ภารกิจ GUI นี้ทำงานร่วมกับองค์ประกอบ HTML <progress> ที่มีอยู่เพื่อช่วยลดภาระในเรื่องการเข้าถึง สีและเลย์เอาต์ผลักดันขีดจำกัดของการปรับแต่งองค์ประกอบในตัวเพื่อทำให้คอมโพเนนต์ทันสมัยและเหมาะกับระบบการออกแบบมากกว่า

แท็บสีอ่อนและสีเข้มในแต่ละเบราว์เซอร์จะแสดงภาพรวมของไอคอนแบบปรับอัตโนมัติจากบนลงล่าง เช่น Safari, Firefox, Chrome
การสาธิตที่แสดงใน Firefox, Safari, iOS Safari, Chrome และ Android Chrome ในรูปแบบสว่างและมืด

Markup

ฉันเลือกรวมองค์ประกอบ <progress> ใน <label> เพื่อจะได้ข้ามแอตทริบิวต์ความสัมพันธ์อย่างชัดแจ้ง และยังติดป้ายกำกับองค์ประกอบระดับบนสุดที่ได้รับผลกระทบจากสถานะการโหลดเอาไว้ด้วย ดังนั้นเทคโนโลยีโปรแกรมอ่านหน้าจอจึงส่งต่อข้อมูลดังกล่าวกลับไปยังผู้ใช้ได้

<progress></progress>

หากไม่มี value ความคืบหน้าขององค์ประกอบจะไม่ชัดเจน แอตทริบิวต์ max มีค่าเริ่มต้นเป็น 1 ความคืบหน้าจึงอยู่ระหว่าง 0 ถึง 1 ตัวอย่างเช่น การตั้งค่า max เป็น 100 จะตั้งค่าช่วงเป็น 0-100 ผมเลือกที่จะอยู่ในขีดจำกัด 0 และ 1 โดยแปลค่าความคืบหน้าเป็น 0.5 หรือ 50%

ความคืบหน้าที่รวมป้ายกำกับ

ในความสัมพันธ์โดยนัย องค์ประกอบความคืบหน้าจะอยู่ภายในป้ายกำกับดังนี้

<label>Loading progress<progress></progress></label>

ในการสาธิต ผมเลือกใส่ป้ายกำกับสำหรับโปรแกรมอ่านหน้าจอเท่านั้น ซึ่งทำได้โดยการตัดข้อความป้ายกำกับใน <span> และนำรูปแบบบางอย่างไปใช้กับข้อความเพื่อให้ปิดหน้าจอได้อย่างมีประสิทธิภาพ ดังนี้

<label>
  <span class="sr-only">Loading progress</span>
  <progress></progress>
</label>

เมื่อใช้ CSS ต่อไปนี้จาก WebAIM

.sr-only {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

ภาพหน้าจอของเครื่องมือสำหรับนักพัฒนาเว็บแสดงองค์ประกอบที่พร้อมใช้งานเท่านั้นสำหรับหน้าจอ

พื้นที่ที่ได้รับผลกระทบจากการโหลด

ถ้าคุณมีสายตาที่ดี ก็สามารถเชื่อมโยงตัวบ่งชี้ความคืบหน้ากับองค์ประกอบที่เกี่ยวข้องและพื้นที่ของหน้าเว็บได้ง่ายๆ แต่สำหรับผู้ใช้ที่มีความบกพร่องทางสายตา จะเห็นได้ไม่ชัดเจนนัก ปรับปรุงประสิทธิภาพนี้โดยการกำหนดแอตทริบิวต์ aria-busy ให้กับองค์ประกอบบนสุดซึ่งจะเปลี่ยนแปลงเมื่อการโหลดเสร็จสมบูรณ์ นอกจากนี้ ให้ระบุความสัมพันธ์ระหว่างความคืบหน้าและโซนการโหลดด้วย aria-describedby

<main id="loading-zone" aria-busy="true">
  …
  <progress aria-describedby="loading-zone"></progress>
</main>

จาก JavaScript ให้สลับ aria-busy เป็น true เมื่อเริ่มงาน และเปลี่ยนไปเป็น false เมื่อเสร็จสิ้น

การเพิ่มแอตทริบิวต์ Aria

แม้ว่าบทบาทโดยนัยขององค์ประกอบ <progress> คือ progressbar แต่ฉันได้ระบุอย่างชัดแจ้งสำหรับเบราว์เซอร์ที่ไม่มีบทบาทโดยนัยดังกล่าว เรายังได้เพิ่มแอตทริบิวต์ indeterminate เพื่อทำให้องค์ประกอบอยู่ในสถานะที่ไม่รู้จักอย่างชัดแจ้ง ซึ่งชัดเจนกว่าการสังเกตการที่องค์ประกอบไม่ได้ตั้งค่า value

<label>
  Loading 
  <progress 
    indeterminate 
    role="progressbar" 
    aria-describedby="loading-zone"
    tabindex="-1"
  >unknown</progress>
</label>

ใช้ tabindex="-1" เพื่อทำให้องค์ประกอบความคืบหน้าโฟกัสได้จาก JavaScript ข้อมูลนี้สำคัญสำหรับเทคโนโลยีโปรแกรมอ่านหน้าจอ เนื่องจากการโฟกัสที่ความคืบหน้าเป็นการเปลี่ยนแปลงความคืบหน้าจะประกาศให้ผู้ใช้ทราบถึงความคืบหน้าที่ได้รับการอัปเดต

รูปแบบ

องค์ประกอบความคืบหน้าจะค่อนข้างซับซ้อนเล็กน้อยในเรื่องการจัดรูปแบบ องค์ประกอบ HTML แบบบิวท์อินมีส่วนพิเศษที่ซ่อนอยู่ซึ่งเลือกยากและมักจะนำเสนอเพียงชุดพร็อพเพอร์ตี้ที่จำกัดเท่านั้น

เลย์เอาต์

รูปแบบเลย์เอาต์มีไว้เพื่อให้ความยืดหยุ่นในขนาดและตำแหน่งป้ายกำกับขององค์ประกอบความคืบหน้า มีการเพิ่มสถานะเสร็จสมบูรณ์แบบพิเศษที่อาจเป็นสัญลักษณ์ภาพเพิ่มเติม แต่ไม่บังคับ

เลย์เอาต์ <progress>

ความกว้างขององค์ประกอบความคืบหน้าไม่มีการเปลี่ยนแปลงใดๆ จึงสามารถย่อและเติบโตได้โดยมีพื้นที่เพียงพอในการออกแบบ รูปแบบในตัวจะถูกตัดออกโดยการตั้งค่า appearance และ border เป็น none วิธีนี้ทำให้ระบบปรับองค์ประกอบให้เป็นมาตรฐานในเบราว์เซอร์ต่างๆ ได้ เนื่องจากแต่ละเบราว์เซอร์มีรูปแบบของตัวเองสำหรับองค์ประกอบ

progress {
  --_track-size: min(10px, 1ex);
  --_radius: 1e3px;

  /*  reset  */
  appearance: none;
  border: none;

  position: relative;
  height: var(--_track-size);
  border-radius: var(--_radius);
  overflow: hidden;
}

ค่าของ 1e3px สำหรับ _radius ใช้สัญลักษณ์ตัวเลขทางวิทยาศาสตร์เพื่อแสดงตัวเลขขนาดใหญ่เพื่อให้ border-radius ปัดเศษเสมอ ซึ่งเทียบเท่ากับ 1000px ฉันชอบใช้ค่านี้เพราะตั้งเป้าไว้ว่าจะใช้ค่าที่ใหญ่มากพอที่ ฉันจะกำหนดได้และไม่ลืมค่าเลย (และเขียนสั้นกว่า 1000px) และยัง ทำให้ใหญ่ขึ้นได้ง่ายๆ หากจำเป็น เพียงเปลี่ยนค่า 3 เป็น 4 จากนั้น 1e4px จะเท่ากับ 10000px

มีการใช้ overflow: hidden และเป็นรูปแบบที่ถกเถียงกันมาก การทำเช่นนี้ทำให้มี 2-3 อย่างง่ายๆ เช่น ไม่จำเป็นต้องส่งค่า border-radius ไปยังแทร็ก และติดตามองค์ประกอบแบบเติมโฆษณา แต่ก็หมายความว่าไม่มีเด็กที่ดำเนินการความคืบหน้าอยู่ภายนอกองค์ประกอบได้ คุณอาจทำซ้ำองค์ประกอบความคืบหน้าที่กำหนดเองนี้ได้อีกโดยไม่มี overflow: hidden และอาจเปิดโอกาสในการทำให้ภาพเคลื่อนไหวหรือสถานะเสร็จสมบูรณ์ที่ดีขึ้นได้

ความคืบหน้าเสร็จสมบูรณ์

ตัวเลือก CSS จะทำงานยากที่นี่โดยการเปรียบเทียบค่าสูงสุดกับค่า และหากตรงกัน ความคืบหน้าจะเสร็จสมบูรณ์ เมื่อเสร็จเรียบร้อยแล้ว ระบบจะสร้างองค์ประกอบจำลองขึ้นและนำไปต่อท้ายองค์ประกอบความคืบหน้าเพื่อให้เป็นจุดชี้นำที่ดีเพิ่มเติมเมื่อเสร็จสมบูรณ์

progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
  content: "✓";
  
  position: absolute;
  inset-block: 0;
  inset-inline: auto 0;
  display: flex;
  align-items: center;
  padding-inline-end: max(calc(var(--_track-size) / 4), 3px);

  color: white;
  font-size: calc(var(--_track-size) / 1.25);
}

ภาพหน้าจอของแถบการโหลดที่ 100% และแสดงเครื่องหมายถูกในตอนท้าย

สี

เบราว์เซอร์มีสีของตัวเองสําหรับองค์ประกอบความคืบหน้า และสามารถปรับให้สว่างและมืดได้ด้วยพร็อพเพอร์ตี้ CSS เพียง 1 รายการ ซึ่งสามารถสร้างขึ้นด้วย ตัวเลือกพิเศษเฉพาะเบราว์เซอร์

รูปแบบเบราว์เซอร์สว่างและมืด

หากต้องการเลือกให้เว็บไซต์ใช้องค์ประกอบ <progress> แบบปรับได้แบบมืดและสว่าง คุณเพียงต้องใช้ color-scheme เท่านั้น

progress {
  color-scheme: light dark;
}

สีเติมความคืบหน้าของพร็อพเพอร์ตี้เดียว

หากต้องการปรับสมดุลสีเขียว-แดงให้องค์ประกอบ <progress> ให้ใช้ accent-color

progress {
  accent-color: rebeccapurple;
}

สังเกตว่าสีพื้นหลังของแทร็กจะเปลี่ยนจากสว่างเป็นมืดโดยขึ้นอยู่กับ accent-color เบราว์เซอร์จะตรวจสอบคอนทราสต์ที่เหมาะสม: ค่อนข้างเป็นระเบียบ

สีสว่างและมืดที่กำหนดเองทั้งหมด

ตั้งค่าพร็อพเพอร์ตี้ที่กำหนดเอง 2 รายการในองค์ประกอบ <progress> โดยแบบแรกสำหรับสีแทร็ก และอีกรายการสำหรับสีความคืบหน้าของแทร็ก ภายในคำค้นหาสื่อ prefers-color-scheme ให้ระบุค่าสีใหม่สำหรับแทร็กและติดตามความคืบหน้า

progress {
  --_track: hsl(228 100% 90%);
  --_progress: hsl(228 100% 50%);
}

@media (prefers-color-scheme: dark) {
  progress {
    --_track: hsl(228 20% 30%);
    --_progress: hsl(228 100% 75%);
  }
}

เน้นรูปแบบ

ก่อนหน้านี้เราให้ดัชนีแท็บเชิงลบแก่องค์ประกอบเพื่อให้เขียนแบบเป็นโปรแกรมได้ ใช้ :focus-visible เพื่อปรับแต่งโฟกัสเพื่อเลือกใช้รูปแบบวงแหวนโฟกัสที่ชาญฉลาดยิ่งขึ้น สำหรับวิธีนี้ การคลิกเมาส์และโฟกัสจะไม่แสดงวงแหวนโฟกัส แต่การคลิกแป้นพิมพ์จะแสดง วิดีโอ YouTube จะอธิบายรายละเอียดนี้อย่างละเอียดยิ่งขึ้นและควรค่าแก่การตรวจสอบ

progress:focus-visible {
  outline-color: var(--_progress);
  outline-offset: 5px;
}

ภาพหน้าจอของแถบแสดงสถานะการโหลดโดยมีวงแหวนโฟกัสอยู่รอบๆ ทุกสีตรงกัน

รูปแบบที่กำหนดเองในเบราว์เซอร์ต่างๆ

ปรับแต่งรูปแบบโดยเลือกส่วนขององค์ประกอบ <progress> ที่เบราว์เซอร์แต่ละรายการแสดง การใช้องค์ประกอบความคืบหน้าเป็นเพียงแท็กเดียว แต่ก็สร้างขึ้นจากองค์ประกอบย่อย 2-3 องค์ประกอบที่แสดงผ่านตัวเลือกเทียมของ CSS เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome จะแสดงองค์ประกอบเหล่านี้ หากคุณเปิดใช้การตั้งค่า

  1. คลิกขวาบนหน้าเว็บและเลือกตรวจสอบองค์ประกอบเพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
  2. คลิกรูปเฟืองการตั้งค่าที่มุมขวาบนของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ
  3. ภายใต้ส่วนหัวองค์ประกอบ ให้ค้นหาและเปิดใช้ช่องทำเครื่องหมายแสดงเงาของ User Agent

ภาพหน้าจอของส่วนในเครื่องมือสำหรับนักพัฒนาเว็บเพื่อเปิดใช้การแสดง DOM ของ User Agent

รูปแบบ Safari และ Chromium

เบราว์เซอร์แบบ WebKit เช่น Safari และ Chromium จะแสดง ::-webkit-progress-bar และ ::-webkit-progress-value ซึ่งทำให้ใช้ CSS บางส่วนได้ สำหรับตอนนี้ ให้ตั้งค่า background-color โดยใช้พร็อพเพอร์ตี้ที่กำหนดเอง ที่สร้างไว้ก่อนหน้านี้ ซึ่งจะปรับเป็นสว่างและมืด

/*  Safari/Chromium  */
progress[value]::-webkit-progress-bar {
  background-color: var(--_track);
}

progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
}

ภาพหน้าจอแสดงองค์ประกอบภายในขององค์ประกอบความคืบหน้า

รูปแบบใน Firefox

Firefox จะแสดงตัวเลือกเทียม ::-moz-progress-bar ในองค์ประกอบ <progress> เท่านั้น ซึ่งหมายความว่าเราไม่สามารถปรับสมดุลสีเขียว-แดงในแทร็กนั้นโดยตรงได้

/*  Firefox  */
progress[value]::-moz-progress-bar {
  background-color: var(--_progress);
}

ภาพหน้าจอของ Firefox และตำแหน่งของส่วนขององค์ประกอบความคืบหน้า

ภาพหน้าจอของมุมการแก้ไขข้อบกพร่องที่ Safari, iOS Safari, Firefox, Chrome และ Chrome ใน Android มีแถบการโหลดที่แสดงว่าใช้งานได้

โปรดสังเกตว่า Firefox ตั้งค่าสีแทร็กจาก accent-color ขณะที่ iOS Safari มีแทร็กสีฟ้าอ่อน โหมดมืดก็เหมือนกันคือ Firefox มีดาร์กแทร็ก แต่ ไม่ใช่สีแบบกำหนดเองที่เราตั้งค่าไว้ และทำงานได้ในเบราว์เซอร์แบบ Webkit

แอนิเมชัน

ขณะที่ทำงานกับตัวเลือกเทียมในตัวของเบราว์เซอร์ ซึ่งมักจะมีชุดพร็อพเพอร์ตี้ CSS ที่ได้รับอนุญาตแบบจำกัด

ภาพเคลื่อนไหวเติมเส้นทางให้เต็มกำลัง

การเพิ่มการเปลี่ยนไปยัง inline-size ขององค์ประกอบความคืบหน้าใช้ได้กับ Chromium แต่ใช้ไม่ได้กับ Safari นอกจากนี้ Firefox ก็ไม่ได้ใช้พร็อพเพอร์ตี้การเปลี่ยนใน ::-moz-progress-bar ด้วย

/*  Chromium Only 😢  */
progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
  transition: inline-size .25s ease-out;
}

การสร้างภาพเคลื่อนไหวจากสถานะ :indeterminate

ทีนี้ฉันก็จะสร้างสรรค์มากขึ้น เพื่อให้ใส่ภาพเคลื่อนไหวได้ ระบบจะสร้างองค์ประกอบเทียมสำหรับ Chromium ขึ้นและมีการใช้การไล่ระดับสีที่เป็นภาพเคลื่อนไหวกลับไปกลับมาสำหรับทั้ง 3 เบราว์เซอร์

พร็อพเพอร์ตี้ที่กำหนดเอง

คุณสมบัติที่กำหนดเองมีประโยชน์สำหรับหลายๆ อย่าง แต่สิ่งที่ฉันชื่นชอบมากที่สุดคือการตั้งชื่อให้กับค่า CSS ที่ดูน่าทึ่ง ขั้นตอนต่อไปนี้ค่อนข้างซับซ้อน linear-gradient แต่เป็นชื่อที่น่าสนใจ ทำให้เข้าใจวัตถุประสงค์และกรณีการใช้งานได้อย่างชัดเจน

progress {
  --_indeterminate-track: linear-gradient(to right,
    var(--_track) 45%,
    var(--_progress) 0%,
    var(--_progress) 55%,
    var(--_track) 0%
  );
  --_indeterminate-track-size: 225% 100%;
  --_indeterminate-track-animation: progress-loading 2s infinite ease;
}

นอกจากนี้ พร็อพเพอร์ตี้ที่กำหนดเองจะช่วยให้โค้ดเป็นแบบ DRY เนื่องจากเราไม่สามารถจัดกลุ่มตัวเลือกเฉพาะเบราว์เซอร์เหล่านี้เข้าด้วยกันได้

คีย์เฟรม

เป้าหมายคือภาพเคลื่อนไหวที่แสดงกลับไปกลับมาเรื่อยๆ คีย์เฟรมเริ่มต้นและสิ้นสุด จะกำหนดใน CSS ต้องการเพียงคีย์เฟรมเดียว นั่นคือคีย์เฟรมกลางที่ 50% เพื่อสร้างภาพเคลื่อนไหวที่กลับไปที่จุดเริ่มต้นของการทำงานซ้ำแล้วซ้ำอีก

@keyframes progress-loading {
  50% {
    background-position: left; 
  }
}

การกำหนดเป้าหมายแต่ละเบราว์เซอร์

บางเบราว์เซอร์ไม่อนุญาตให้สร้างองค์ประกอบจำลองบนองค์ประกอบ <progress> เอง หรืออนุญาตให้แถบความคืบหน้าเคลื่อนไหว มีเบราว์เซอร์มากกว่า 1 อย่างที่รองรับการสร้างภาพเคลื่อนไหวของแทร็กมากกว่าองค์ประกอบเทียม ฉันจึงอัปเกรดจากองค์ประกอบเทียมเป็นฐานและเป็นแถบเคลื่อนไหว

องค์ประกอบเทียมของ Chromium

Chromium ไม่อนุญาตให้ใช้องค์ประกอบเทียม: ::after กับตำแหน่งเพื่อปกปิดองค์ประกอบ มีการใช้คุณสมบัติที่กำหนดเองแบบไม่ชัดเจน และภาพเคลื่อนไหวแบบกลับไปกลับมาทำงานได้ดี

progress:indeterminate::after {
  content: "";
  inset: 0;
  position: absolute;
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
แถบความคืบหน้าของ Safari

สำหรับ Safari คุณสมบัติที่กำหนดเองและภาพเคลื่อนไหวจะมีผลกับแถบความคืบหน้าขององค์ประกอบจำลองดังนี้

progress:indeterminate::-webkit-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
แถบความคืบหน้าของ Firefox

สำหรับ Firefox คุณสมบัติที่กำหนดเองและภาพเคลื่อนไหวจะมีผลกับแถบความคืบหน้าขององค์ประกอบเทียมด้วย

progress:indeterminate::-moz-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}

JavaScript

JavaScript มีบทบาทสำคัญกับองค์ประกอบ <progress> โดยจะควบคุมค่าที่ส่งไปยังองค์ประกอบและดูแลให้มีข้อมูลมากพอในเอกสารสำหรับโปรแกรมอ่านหน้าจอ

const state = {
  val: null
}

การสาธิตจะมีปุ่มสำหรับควบคุมความคืบหน้า โดยจะอัปเดต state.val จากนั้นเรียกใช้ฟังก์ชันเพื่ออัปเดต DOM

document.querySelector('#complete').addEventListener('click', e => {
  state.val = 1
  setProgress()
})

setProgress()

ฟังก์ชันนี้คือจุดที่มีการแสดง UI/UX เป็นกลุ่ม เริ่มต้นใช้งานโดยการสร้างฟังก์ชัน setProgress() ไม่จำเป็นต้องใช้พารามิเตอร์เนื่องจากมีสิทธิ์เข้าถึงออบเจ็กต์ state, องค์ประกอบความคืบหน้า และโซน <main>

const setProgress = () => {
  
}

กำลังตั้งค่าสถานะการโหลดในโซน <main>

องค์ประกอบ <main> ที่เกี่ยวข้องต้องอัปเดตแอตทริบิวต์ aria-busy ดังต่อไปนี้ ขึ้นอยู่กับว่าความคืบหน้าเสร็จสมบูรณ์หรือไม่

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)
}

ล้างแอตทริบิวต์หากไม่ทราบจำนวนเงินที่โหลด

หากไม่ทราบค่าหรือไม่ได้ตั้งค่า null ในการใช้งานนี้ ให้นำแอตทริบิวต์ value และ aria-valuenow ออก ซึ่งจะเปลี่ยน <progress> เป็นไม่ทราบ

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }
}

แก้ไขปัญหาการคำนวณทศนิยมของ JavaScript

เนื่องจากผมเลือกใช้ค่าเริ่มต้นความคืบหน้าสูงสุดคือ 1 ฟังก์ชัน การเพิ่มและการลดของการสาธิตจะใช้การคำนวณทศนิยม JavaScript และภาษาอื่นๆ อาจทำงานได้ไม่ดีเสมอไป นี่คือฟังก์ชัน roundDecimals() ที่จะตัดผลลัพธ์ทางคณิตศาสตร์ที่เกินมาออก

const roundDecimals = (val, places) =>
  +(Math.round(val + "e+" + places)  + "e-" + places)

ปัดเศษค่าเพื่อให้มองเห็นและอ่านได้ชัดเจน ดังนี้

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"
}

กำหนดค่าสำหรับโปรแกรมอ่านหน้าจอและสถานะเบราว์เซอร์

ค่านี้จะใช้ใน 3 ตำแหน่งใน DOM ได้แก่

  1. แอตทริบิวต์ value ขององค์ประกอบ <progress>
  2. แอตทริบิวต์ aria-valuenow
  3. เนื้อหาข้อความภายใน <progress>
const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent
}

มุ่งเน้นไปที่ความคืบหน้า

อัปเดตค่าแล้ว ผู้ใช้ที่มองเห็นจะเห็นการเปลี่ยนแปลงความคืบหน้า แต่ผู้ใช้โปรแกรมอ่านหน้าจอยังไม่ได้รับประกาศการเปลี่ยนแปลง โฟกัสองค์ประกอบ <progress> แล้วเบราว์เซอร์จะประกาศการอัปเดต

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent

  progress.focus()
}

ภาพหน้าจอของแอป Voice Over ใน Mac OS ที่กำลังอ่านความคืบหน้าของแถบการโหลดให้ผู้ใช้เห็น

บทสรุป

ตอนนี้คุณก็รู้แล้วว่าตัวเองทำยังไง คุณจะทำอะไรบ้าง‽ 🙂

แน่นอนว่ามีการเปลี่ยนแปลงบางอย่างที่เราอยากทําหากให้โอกาสอีกครั้ง ฉันคิดว่ายังมีพื้นที่ให้ล้างคอมโพเนนต์ปัจจุบัน และมีพื้นที่ให้ลองสร้างคอมโพเนนต์โดยไม่มีข้อจำกัดด้านรูปแบบคลาส Pseudo ขององค์ประกอบ <progress> น่าสำรวจ!

มาลองเปลี่ยนแนวทางของเราและเรียนรู้วิธีทั้งหมดเพื่อสร้างเว็บกันเถอะ

สร้างเดโม ลิงก์ทวีตฉัน แล้วฉันจะเพิ่มลงในส่วนรีมิกซ์ของชุมชนด้านล่าง

รีมิกซ์ของชุมชน