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

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

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

Chrome पर, लाइट और डार्क, अनिश्चित, बढ़ने वाला, और पूरा होने वाला प्रोग्रेस बार दिखाया गया है.

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

खास जानकारी

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

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

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

मार्कअप

मैंने <progress> एलिमेंट को <label> में रैप किया है, ताकि एक्सप्लिसिट रिलेशनशिप एट्रिब्यूट के बजाय इंप्लिसिट रिलेशनशिप का इस्तेमाल किया जा सके. मैंने लोडिंग की स्थिति से प्रभावित होने वाले पैरंट एलिमेंट को भी लेबल किया है, ताकि स्क्रीन रीडर टेक्नोलॉजी उस जानकारी को उपयोगकर्ता को वापस भेज सकें.

<progress></progress>

अगर कोई value नहीं है, तो एलिमेंट की प्रोग्रेस indeterminate होती है. 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 में उस जगह का स्क्रीनशॉट जहां उपयोगकर्ता एजेंट शैडो DOM को दिखाने की सुविधा चालू की जा सकती है.

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 स्यूडो-एलिमेंट

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()

इस फ़ंक्शन में, यूज़र इंटरफ़ेस (यूआई) और उपयोगकर्ता अनुभव (यूएक्स) को व्यवस्थित किया जाता है. 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 में दशमलव वाली संख्याओं के गणित से जुड़ी समस्याओं को ठीक करना

मैंने प्रोग्रेस के डिफ़ॉल्ट तौर पर ज़्यादा से ज़्यादा एक वैल्यू का इस्तेमाल किया है. इसलिए, डेमो में वैल्यू बढ़ाने और घटाने वाले फ़ंक्शन, दशमलव वाली गणित का इस्तेमाल करते हैं. 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> एलिमेंट की स्यूडो-क्लास स्टाइल से जुड़ी सीमाओं के बिना एक नया कॉम्पोनेंट बनाया जा सकता है. इसे एक्सप्लोर करना वाकई बनता है!

आइए, हम अपने तरीकों में विविधता लाएं और वेब पर काॅन्टेंट पोस्ट करने के सभी तरीके जानें.

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

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