प्रॉम्प्ट और संदर्भ
सर्च, सेव और अपलोड बिना किसी नेविगेशन या फोकस बदले पूरे होते हैं। दृश्य यूज़र्स को “Saving”, “Saved” या “Save failed” दिखाई देता है, जबकि यह अपडेट फोकस्ड कंट्रोल के बाहर हो सकता है। इसका लक्ष्य एक संक्षिप्त, कार्रवाई योग्य (actionable) अनाउंसमेंट प्रदान करना है जो इनपुट में बाधा न डाले, साथ ही कीबोर्ड, नो-स्क्रिप्ट और नेटवर्क-विफलता के फ़ॉलबैक भी मौजूद हों।
इंटरव्यूअर क्या जांचता है
उत्तर में केवल एक aria-live एट्रिब्यूट जोड़ने के बजाय, एडवाइज़री स्टेटस, एरर्स और ज़रूरी अलर्ट्स के बीच अंतर करना; अपडेट से पहले एक लाइव रीजन स्थापित करना; डुप्लिकेट अनाउंसमेंट्स, रेस कंडीशन्स और फोकस मूवमेंट को नियंत्रित करना; और सर्वर रिजल्ट्स, पुनः प्रयास (retry) कार्रवाइयों व टेस्टिंग को शामिल करना स्पष्ट होना चाहिए।
स्पष्ट करने हेतु प्रश्न
- कौन से अपडेट एडवाइज़री हैं, और कौन से अगली कार्रवाई को रोकते हैं?
- क्या यूज़र्स समवर्ती (concurrent) रिक्वेस्ट्स ट्रिगर कर सकते हैं, और क्या रिस्पॉन्स में सीक्वेंस नंबर होते हैं?
- क्या विफलता पर इनलाइन रीट्राय, अनडू या विवरण देखने की कार्रवाई उपलब्ध है?
- क्या सफलता के बाद फोकस एडिटर में ही रहना चाहिए, और एरर होने पर इसे कहाँ जाना चाहिए?
- क्या सामान्य फॉर्म सबमिशन, कीबोर्ड का उपयोग, ज़ूम और फोर्स्ड कलर्स (forced colors) की आवश्यकता है?
30-सेकंड का उत्तर
मैं शुरुआती DOM में एक खाली role="status" रीजन रेंडर करूँगा और उसमें सामान्य प्रगति और पूर्णता के संदेश लिखूँगा। इसके विनम्र (polite) व्यवहार के कारण फोकस नहीं हटना चाहिए। कार्रवाई योग्य एरर्स को कंट्रोल के पास दृश्य टेक्स्ट और एक रिकवरी पाथ मिलता है; केवल वास्तव में ज़रूरी इवेंट्स ही अलर्ट का उपयोग करते हैं। मैं अनाउंसमेंट्स को डिडुप्लिकेट और थ्रॉटल करूँगा, सीक्वेंस नंबर द्वारा पुराने (stale) रिस्पॉन्स को खारिज करूँगा, और कीबोर्ड, स्क्रीन रीडर, नेटवर्क विफलता व समवर्ती रिक्वेस्ट्स का परीक्षण करूँगा।
चरण-दर-चरण विस्तृत उत्तर
चरण 1: स्थिति (state) को स्पष्ट रूप से मॉडल करें
idle, pending, success, error, और cancelled को अलग-अलग रखें। स्टेटस रीजन आंतरिक रिक्वेस्ट नामों या प्रत्येक प्रतिशत के बजाय वर्तमान परिणाम बताता है, जैसे कि “Saving”, “Saved”, या “Save failed; retry”। फ़ील्ड एरर्स, रीट्राय कार्रवाइयों और कंट्रोल एसोसिएशनों को अलग से स्टोर करें।
चरण 2: पहले लाइव रीजन बनाएं
W3C और MDN सामग्री बदलने से पहले लाइव रीजन बनाने की सलाह देते हैं। role="status" एडवाइज़री जानकारी के लिए उपयुक्त है और इसमें एक अंतर्निहित aria-live="polite" होता है; केवल अपडेट होने पर ही एट्रिब्यूट न जोड़ें।
<p id="save-status" role="status" aria-atomic="true"></p>
<button type="submit">Save</button>चरण 3: अनाउंसमेंट की गति (cadence) को नियंत्रित करें
सर्च के दौरान एक ही टेक्स्ट को बार-बार न लिखें और न ही हर कीस्ट्रोक की घोषणा करें। उच्च-आवृत्ति वाले परिणामों को डिबाउंस (debounce) करें और “Results updated” जैसा एक सार्थक सारांश घोषित करें। पूर्णता, विफलता और आवश्यक कार्रवाई में अगले कदम का उल्लेख होना चाहिए। aria-live="assertive" स्पीच को बीच में रोकता है और इसका उपयोग दुर्लभ होना चाहिए।
चरण 4: रेस कंडीशन्स और रद्दीकरण (cancellation) को संभालें
प्रत्येक रिक्वेस्ट को एक बढ़ता हुआ सीक्वेंस नंबर या एक AbortController दें। केवल माउंटेड कंपोनेंट से आने वाला नवीनतम रिस्पॉन्स ही स्टेटस को अपडेट कर सकता है। रद्द की गई रिक्वेस्ट विफलता की अनाउंसमेंट नहीं होती; एक नई रिक्वेस्ट पिछले पेंडिंग संदेश को बदल देती है।
चरण 5: फोकस और एरर्स का समन्वय करें
सामान्य सफलता पर फोकस न बदलें; यूज़र को कार्य जारी रखने दें। विफलता के लिए, दृश्य टेक्स्ट रेंडर करें और इसे aria-describedby का उपयोग करके कंट्रोल के साथ संबद्ध करें; पेज-स्तरीय विफलताओं के लिए एक फोकसेबल सारांश और रीट्राय बटन की आवश्यकता होती है। एक प्राथमिक चैनल चुनें ताकि फोकस जंप और लाइव अनाउंसमेंट एक-दूसरे की नकल न करें।
चरण 6: फ़ॉलबैक पाथ सुरक्षित रखें
सर्वर को अभी भी सामान्य फॉर्म सबमिशन स्वीकार करना चाहिए और संरचित परिणाम वापस करने चाहिए। जावास्क्रिप्ट विफलता, टाइमआउट, या समाप्त अनुमति पर, टेक्स्ट को केवल स्पिनर छोड़ने के बजाय स्थिति और कार्रवाई बतानी चाहिए, जैसे कि “Save failed; try again”। यूज़र का इनपुट न हटाएं।
ट्रेड-ऑफ़ और सीमाएं
status, alert, और दृश्य एरर्स
status विनम्र (polite) सूचना के लिए है; alert बाधित करता है और इसे हर एरर के स्थान पर उपयोग नहीं किया जाना चाहिए। दृश्य एरर्स अभी भी आवश्यक हैं क्योंकि स्पीच ही एकमात्र चैनल नहीं है। रंग, आइकन और एनिमेशन टेक्स्ट के पूरक होते हैं।
प्रगति विवरण बनाम अवांछित शोर (noise)
अपलोड प्रतिशत को दृष्टिगत रूप से दिखाएं, लेकिन केवल शुरुआत, सार्थक चरणों और पूर्णता की घोषणा करें। लाइव रीजन को हर एक प्रतिशत पर अपडेट करने से शोर पैदा होता है; वास्तविक उपकरणों और यूज़र्स के साथ थ्रॉटलिंग को कैलिब्रेट करें।
रोलआउट योजना और प्रमाण
कंपोनेंट और API अनुबंध
संदेश टेक्स्ट, डिडुप्लिकेशन और सीक्वेंस जांच को एक ही स्टेटस कंपोनेंट में केंद्रीकृत करें। API संरचित success, retryable, और fieldErrors फ़ील्ड लौटाता है; कंपोनेंट सर्वर कोड को सीधे दिखाने के बजाय उन्हें यूज़र की भाषा में मैप करता है।
सत्यापन मैट्रिक्स
कीबोर्ड द्वारा सर्च, सेव और अपलोड पूरा करें और NVDA तथा VoiceOver में एक अनाउंसमेंट की पुष्टि करें। धीमे नेटवर्क, टाइमआउट, डबल क्लिक, आउट-ऑफ-ऑर्डर रिस्पॉन्स, रद्दीकरण, अनलोड, फोर्स्ड कलर्स और 200% ज़ूम को कवर करें। DOM सेमांटिक्स को स्वचालित रूप से टेस्ट करें, फिर बोले जाने वाले क्रम को मैन्युअल रूप से सत्यापित करें।
सामान्य गलतियाँ और फॉलो-अप्स
गलती: aria-live को डायनेमिक रूप से जोड़ना
नोड और एट्रिब्यूट को पहले से मौजूद रखें, फिर उसके टेक्स्ट को अपडेट करें; अन्यथा कुछ सहायक तकनीकें पहले बदलाव को मिस कर सकती हैं।
गलती: फोकस को सक्सेस टेक्स्ट पर ले जाना
यह संपादन (editing) में बाधा डालता है। जब तक यूज़र को किसी एरर को ठीक न करना हो या परिणाम की जांच न करनी हो, फोकस वहीं रहने दें।
गलती: हर एरर को assertive बनाना
उच्च-प्राथमिकता वाली स्पीच पढ़ने में बाधा डालती है। इसे केवल वास्तव में तत्काल ध्यान देने योग्य मामलों के लिए सुरक्षित रखें और दृश्य रिकवरी प्रदान करें।
फॉलो-अप: पुराने रिस्पॉन्स को रोकना
एक मोनोटोनिक सीक्वेंस की तुलना करें, या रद्दीकरण को सीक्वेंस जांच के साथ संयोजित करें; केवल रद्दीकरण यह साबित नहीं करता कि कोई कॉलबैक नहीं चल सकता।
फॉलो-अप: प्रभावशीलता साबित करना
केवल एक स्वचालित स्कैन परिणाम के बजाय स्क्रीन-रीडर प्रेक्षण, कीबोर्ड प्रवाह, नेटवर्क विफलताएं और रेस-कंडीशन के प्रमाण प्रस्तुत करें।