लोडिंग बार कॉम्पोनेंट बनाना

<progress> एलिमेंट की मदद से, रंग के हिसाब से अडैप्ट होने वाला और सुलभ लोडिंग बार बनाने के तरीके के बारे में बुनियादी जानकारी.

इस पोस्ट में, हम <progress> एलिमेंट की मदद से, रंग के हिसाब से अडजस्ट होने वाला और सुलभ लोडिंग बार बनाने के बारे में बताएंगे. डेमो आज़माएं और सोर्स देखें!

Chrome पर लाइट और डार्क, इंडिटरमिनेट, प्रोग्रेस, और टास्क पूरा होने का डेमो.

अगर आपको वीडियो देखना पसंद है, तो इस पोस्ट का YouTube वर्शन यहां देखें:

खास जानकारी

<progress> एलिमेंट, उपयोगकर्ताओं को विज़ुअल और ऑडियो के ज़रिए यह जानकारी देता है कि प्रोसेस पूरी हो गई है. यह विज़ुअल फ़ीडबैक, इन स्थितियों में काम आता है: फ़ॉर्म भरने की प्रोसेस, डाउनलोड या अपलोड करने की जानकारी दिखाना या यह दिखाना कि प्रोग्रेस की जानकारी नहीं है, लेकिन काम अब भी जारी है.

इस जीयूआई चैलेंज में, सुलभता को बेहतर बनाने के लिए, मौजूदा एचटीएमएल <progress> एलिमेंट का इस्तेमाल किया गया. रंग और लेआउट, पहले से मौजूद एलिमेंट को पसंद के मुताबिक बनाने की सीमाओं को बढ़ाते हैं. इससे कॉम्पोनेंट को आधुनिक बनाया जा सकता है और उसे डिज़ाइन सिस्टम में बेहतर तरीके से फ़िट किया जा सकता है.

हर ब्राउज़र में लाइट और डार्क टैब, अडैप्टिव आइकॉन की खास जानकारी देते हैं. 
    यह जानकारी ऊपर से नीचे की ओर दी गई है: 
    Safari, Firefox, Chrome.
Firefox, Safari, iOS Safari, Chrome, और Android Chrome पर लाइट और डार्क स्कीम में दिखाया गया डेमो.

मार्कअप

मैंने <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>

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>

JavaScript से प्रोग्रेस एलिमेंट को फ़ोकस करने लायक बनाने के लिए, tabindex="-1" का इस्तेमाल करें. यह स्क्रीन रीडर टेक्नोलॉजी के लिए ज़रूरी है, क्योंकि प्रोग्रेस बदलने पर प्रोग्रेस फ़ोकस देने से, उपयोगकर्ता को पता चलेगा कि अपडेट की गई प्रोग्रेस कितनी दूर तक पहुंच गई है.

स्टाइल

प्रोग्रेस एलिमेंट को स्टाइल करना थोड़ा मुश्किल होता है. पहले से मौजूद एचटीएमएल एलिमेंट में, छिपे हुए कुछ खास हिस्से होते हैं. इन्हें चुनना मुश्किल हो सकता है. साथ ही, इनमें अक्सर सेट करने के लिए प्रॉपर्टी का एक सीमित सेट ही मिलता है.

लेआउट

लेआउट स्टाइल की मदद से, प्रोग्रेस एलिमेंट के साइज़ और लेबल की पोज़िशन में कुछ हद तक बदलाव किया जा सकता है. पूरा होने की एक खास स्थिति जोड़ी गई है. यह एक मददगार, लेकिन ज़रूरी नहीं, अतिरिक्त विज़ुअल संकेत हो सकता है.

<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;
}

_radius के लिए 1e3px की वैल्यू, साइंटिफ़िक नंबर नोटेशन का इस्तेमाल करती है, ताकि बड़ी संख्या को दिखाया जा सके. इसलिए, border-radius को हमेशा राउंड किया जाता है. यह 1000px के बराबर है. मुझे इसका इस्तेमाल करना पसंद है, क्योंकि मेरा मकसद ऐसी वैल्यू का इस्तेमाल करना है जो इतनी बड़ी हो कि उसे सेट करने के बाद, मुझे उसे बदलने की ज़रूरत न पड़े. साथ ही, इसे 1000px के मुकाबले लिखना आसान है. ज़रूरत पड़ने पर, इसे और भी बड़ा किया जा सकता है: बस 3 को बदलकर 4 करें. इसके बाद, 1e4px, 10000px के बराबर हो जाएगा.

overflow: hidden का इस्तेमाल किया जाता है. यह स्टाइल विवादित रहा है. इससे कुछ चीज़ें आसान हो गईं. जैसे, ट्रैक और ट्रैक फ़िल एलिमेंट को border-radius वैल्यू पास करने की ज़रूरत नहीं पड़ी. हालांकि, इसका मतलब यह भी था कि प्रोग्रेस का कोई भी चाइल्ड एलिमेंट, एलिमेंट के बाहर नहीं रह सकता. इस कस्टम प्रोग्रेस एलिमेंट को overflow: hidden के बिना भी दोहराया जा सकता है. इससे ऐनिमेशन या बेहतर तरीके से पूरा होने की स्थितियों के लिए कुछ अवसर मिल सकते हैं.

प्रोसेस पूर्ण

सीएसएस सिलेक्टर, ज़्यादा से ज़्यादा वैल्यू की तुलना वैल्यू से करके मुश्किल काम को आसान बनाते हैं. अगर दोनों वैल्यू मैच हो जाती हैं, तो प्रोग्रेस पूरी हो जाती है. पूरा होने पर, एक सूडो-एलिमेंट जनरेट होता है और प्रोग्रेस एलिमेंट के आखिर में जुड़ जाता है. इससे, टास्क पूरा होने का एक अच्छा विज़ुअल संकेत मिलता है.

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% लोड होने के बाद सही का निशान दिख रहा है.

रंग

ब्राउज़र, प्रोग्रेस एलिमेंट के लिए अपने रंग लाता है. साथ ही, सिर्फ़ एक सीएसएस प्रॉपर्टी की मदद से, लाइट और डार्क मोड के हिसाब से अडजस्ट हो जाता है. इसे कुछ खास ब्राउज़र-विशिष्ट सिलेक्टर के साथ बनाया जा सकता है.

ब्राउज़र के लिए हल्के और गहरे रंग वाली स्टाइल

अपनी साइट को गहरे और हल्के रंग के हिसाब से अडैप्ट होने वाले <progress> एलिमेंट में ऑप्ट इन करने के लिए, आपको सिर्फ़ color-scheme की ज़रूरत होगी.

progress {
  color-scheme: light dark;
}

सिंगल प्रॉपर्टी प्रोग्रेस फ़िल्ड कलर

<progress> एलिमेंट को टिंट करने के लिए, accent-color का इस्तेमाल करें.

progress {
  accent-color: rebeccapurple;
}

ध्यान दें कि ट्रैक का बैकग्राउंड, accent-color के हिसाब से हल्के से गहरे रंग में बदल जाता है. ब्राउज़र यह पक्का कर रहा है कि कंट्रास्ट सही हो: यह बहुत अच्छी बात है.

हल्के और गहरे रंगों को अपनी पसंद के मुताबिक पूरी तरह से सेट करने की सुविधा

<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> एलिमेंट के हिस्सों को चुनकर, स्टाइल को पसंद के मुताबिक बनाएं. प्रोग्रेस एलिमेंट का इस्तेमाल करना एक सिंगल टैग है. हालांकि, यह कुछ चाइल्ड एलिमेंट से बना होता है, जो सीएसएस स्यूडो सिलेक्टर के ज़रिए दिखते हैं. अगर आपने सेटिंग चालू की है, तो Chrome DevTools आपको ये एलिमेंट दिखाएगा:

  1. DevTools को खोलने के लिए, अपने पेज पर राइट क्लिक करें और एलिमेंट की जांच करें को चुनें.
  2. DevTools विंडो के सबसे ऊपर दाएं कोने में मौजूद, सेटिंग गियर पर क्लिक करें.
  3. Elements हेडिंग में जाकर, Show user agent shadow DOM चेकबॉक्स को ढूंढें और उसे चालू करें.

DevTools में उपयोगकर्ता एजेंट शैडो डीओएम को एक्सपोज़ करने की सुविधा चालू करने का स्क्रीनशॉट.

Safari और Chromium स्टाइल

WebKit पर आधारित ब्राउज़र, जैसे कि Safari और Chromium, ::-webkit-progress-bar और ::-webkit-progress-value को एक्सपोज़ करते हैं. इनसे सीएसएस के सबसेट का इस्तेमाल किया जा सकता है. फ़िलहाल, पहले बनाई गई कस्टम प्रॉपर्टी का इस्तेमाल करके, background-color को सेट करें. ये प्रॉपर्टी, लाइट और डार्क थीम के हिसाब से अडजस्ट हो जाती हैं.

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

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

प्रोग्रेस एलिमेंट के अंदरूनी एलिमेंट दिखाने वाला स्क्रीनशॉट.

Firefox की स्टाइल

Firefox, <progress> एलिमेंट पर सिर्फ़ ::-moz-progress-bar स्यूडो सिलेक्टर को दिखाता है. इसका मतलब है कि हम ट्रैक को सीधे तौर पर टिंट नहीं कर सकते.

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

Firefox का स्क्रीनशॉट और प्रोग्रेस एलिमेंट के हिस्सों को ढूंढने का तरीका.

डीबगिंग कॉर्नर का स्क्रीनशॉट, जिसमें Safari, iOS Safari, Firefox, Chrome, और Android पर Chrome, सभी में लोडिंग बार काम करता हुआ दिख रहा है.

ध्यान दें कि Firefox में accent-color से ट्रैक का रंग सेट किया गया है, जबकि iOS Safari में ट्रैक का रंग हल्का नीला है. गहरे रंग वाले मोड में भी ऐसा ही होता है: Firefox में गहरे रंग का ट्रैक होता है, लेकिन इसमें वह रंग नहीं होता जो हमने सेट किया है. हालांकि, यह Webkit पर आधारित ब्राउज़र में काम करता है.

ऐनिमेशन

ब्राउज़र में पहले से मौजूद सूडो सिलेक्टर के साथ काम करते समय, अक्सर अनुमति वाली सीएसएस प्रॉपर्टी का एक सीमित सेट होता है.

ट्रैक भरने का ऐनिमेशन

प्रोग्रेस एलिमेंट के 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 के लिए एक सूडो-एलिमेंट बनाया जाता है और एक ग्रेडिएंट लागू किया जाता है. यह ग्रेडिएंट, तीनों ब्राउज़र के लिए आगे-पीछे ऐनिमेट होता है.

कस्टम प्रॉपर्टी

कस्टम प्रॉपर्टी कई चीज़ों के लिए बेहतरीन होती हैं. हालांकि, मुझे सबसे ज़्यादा पसंद है कि किसी सीएसएस वैल्यू को नाम दिया जाए, जो देखने में जादुई लगती है. यह एक काफ़ी मुश्किल 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 रखने में भी मदद करेंगी. ऐसा इसलिए, क्योंकि हम ब्राउज़र के हिसाब से बनाए गए इन सिलेक्टर को एक साथ ग्रुप नहीं कर सकते.

कीफ़्रेम

इसका मकसद, एक ऐसा ऐनिमेशन बनाना है जो लगातार आगे-पीछे होता रहे. शुरू और खत्म होने वाले कीफ़्रेम, सीएसएस में सेट किए जाएंगे. सिर्फ़ एक कीफ़्रेम की ज़रूरत है, 50% पर मौजूद बीच वाला कीफ़्रेम, ताकि ऐसा ऐनिमेशन बनाया जा सके जो बार-बार वहीं वापस आ जाए जहां से शुरू हुआ था!

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

हर ब्राउज़र को टारगेट करना

हर ब्राउज़र, <progress> एलिमेंट पर सूडो-एलिमेंट बनाने या प्रोग्रेस बार को ऐनिमेट करने की अनुमति नहीं देता. स्यूडो-एलिमेंट के मुकाबले, ज़्यादा ब्राउज़र ट्रैक को ऐनिमेट करने की सुविधा देते हैं. इसलिए, मैं स्यूडो-एलिमेंट से अपग्रेड करके, बार को ऐनिमेट करने की सुविधा का इस्तेमाल करता हूं.

Chromium pseudo-element

Chromium, pseudo-element: ::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()

इस फ़ंक्शन में, यूज़र इंटरफ़ेस (यूआई)/उपयोगकर्ता अनुभव (यूएक्स) को व्यवस्थित किया जाता है. 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 + "%"
}

स्क्रीन रीडर और ब्राउज़र की स्थिति के लिए वैल्यू सेट करना

इस वैल्यू का इस्तेमाल, DOM में तीन जगहों पर किया जाता है:

  1. <progress> एलिमेंट का value एट्रिब्यूट.
  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()
}

Mac OS Voice Over ऐप्लिकेशन का स्क्रीनशॉट, जिसमें उपयोगकर्ता को लोडिंग बार की प्रोग्रेस के बारे में बताया जा रहा है.

नतीजा

अब जब आपको पता चल गया है कि मैंने यह कैसे किया, तो आप इसे कैसे करेंगे/करेंगी‽ 🙂

अगर मुझे फिर से मौका मिले, तो मैं कुछ बदलाव ज़रूर करना चाहूंगा. मुझे लगता है कि मौजूदा कॉम्पोनेंट को बेहतर बनाने की गुंजाइश है. साथ ही, <progress> एलिमेंट की स्यूडो-क्लास स्टाइल की सीमाओं के बिना, एक कॉम्पोनेंट बनाने की कोशिश की जा सकती है. यह एक्सप्लोर करने लायक है!

आइए, वेब पर कॉन्टेंट बनाने के अलग-अलग तरीकों के बारे में जानें.

एक डेमो बनाएं, मुझे लिंक ट्वीट करें, और मैं इसे नीचे कम्यूनिटी रीमिक्स सेक्शन में जोड़ दूंगा!

कम्यूनिटी रीमिक्स