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

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

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

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

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

ภาพรวม

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

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

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

Markup

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

<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 เมื่อดำเนินการเสร็จสิ้น

การเพิ่มแอตทริบิวต์ของอารียา

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

  1. คลิกขวาที่หน้าเว็บแล้วเลือกตรวจสอบองค์ประกอบเพื่อเรียกเครื่องมือสำหรับนักพัฒนาเว็บขึ้นมา
  2. คลิกเฟืองการตั้งค่าที่มุมขวาบนของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ
  3. ภายใต้ส่วนหัวElements ให้ค้นหาและเปิดใช้เงาแสดงเงา User Agent 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;
}

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

คีย์เฟรม

เป้าหมายคือภาพเคลื่อนไหวไม่รู้จบที่กลับไปกลับมา จุดเริ่มต้นและสิ้นสุด ระบบจะตั้งค่าคีย์เฟรมใน CSS ต้องการเพียงคีย์เฟรมเดียว ส่วนคีย์เฟรมกลาง ที่ 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()
}

ภาพหน้าจอแสดงแอป VoiceOver ใน Mac OS 
  อ่านความคืบหน้าของแถบการโหลดให้ผู้ใช้ฟัง

บทสรุป

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

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

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

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

รีมิกซ์ในชุมชน