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

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

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

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

หากต้องการดูวิดีโอ โปรดดูโพสต์นี้ใน YouTube

ภาพรวม

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

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

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

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 และเป็นรูปแบบที่ทำให้เกิดการโต้เถียง ซึ่งทำให้การดำเนินการบางอย่างง่ายขึ้น เช่น ไม่จำเป็นต้องส่งค่า 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 เพียงรายการเดียว ซึ่งสามารถสร้างขึ้นได้ด้วยตัวเลือกเฉพาะเบราว์เซอร์บางตัว

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

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

progress {
  color-scheme: light dark;
}

สีที่เติมความคืบหน้าของที่พักรายการเดียว

หากต้องการเปลี่ยนสี<progress>องค์ประกอบ ให้ใช้ accent-color

progress {
  accent-color: rebeccapurple;
}

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

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

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

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. คลิกไอคอนเฟืองการตั้งค่าที่มุมขวาบนของหน้าต่าง DevTools
  3. ในส่วนหัวองค์ประกอบ ให้ค้นหาและเลือกช่องทำเครื่องหมายแสดง User Agent Shadow DOM

ภาพหน้าจอของตำแหน่งในเครื่องมือสำหรับนักพัฒนาเว็บที่ใช้เปิดใช้การแสดง Shadow 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 คุณต้องใช้คีย์เฟรมเพียง 1 รายการ ซึ่งก็คือคีย์เฟรมตรงกลาง ที่ 50% เพื่อสร้างภาพเคลื่อนไหวที่กลับไปยังจุดเริ่มต้นซ้ำแล้วซ้ำเล่า

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

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

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

องค์ประกอบเสมือนของ 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 
  ที่อ่านความคืบหน้าของแถบโหลดให้ผู้ใช้ฟัง

บทสรุป

ตอนนี้คุณรู้วิธีที่ฉันใช้แล้ว คุณจะทำอย่างไร 🙂

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

มาลองใช้แนวทางที่หลากหลายและเรียนรู้วิธีต่างๆ ในการสร้างสรรค์บนเว็บกัน

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

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