Chrome DevTools में, टॉप लेयर एलिमेंट के लिए सहायता जोड़ी जा रही है. इससे डेवलपर, टॉप लेयर एलिमेंट का इस्तेमाल करने वाले अपने कोड को आसानी से डीबग कर पाएंगे.
इस लेख में बताया गया है कि टॉप लेयर एलिमेंट क्या होते हैं. साथ ही, यह भी बताया गया है कि DevTools, टॉप लेयर कॉन्टेंट को विज़ुअलाइज़ करने में कैसे मदद करता है, ताकि टॉप लेयर एलिमेंट वाले DOM स्ट्रक्चर को समझा और डीबग किया जा सके. इसके अलावा, यह भी बताया गया है कि DevTools टॉप लेयर की सहायता को कैसे लागू किया जाता है.
टॉप लेयर और टॉप लेयर एलिमेंट क्या होते हैं?
जब किसी <dialog>
को मॉडल के तौर पर खोला जाता है, तो अंदरूनी तौर पर क्या होता है? 🤔
इसे सबसे ऊपर की लेयर में रखा जाता है. टॉप लेयर का कॉन्टेंट, दूसरे सभी कॉन्टेंट के ऊपर रेंडर होता है. उदाहरण के लिए, किसी मोडल डायलॉग को अन्य सभी DOM कॉन्टेंट के ऊपर दिखना चाहिए. इसलिए, ब्राउज़र इस एलिमेंट को 'टॉप लेयर' में अपने-आप रेंडर करता है. इससे, लेखकों को z-index को मैन्युअल तरीके से सेट करने की ज़रूरत नहीं पड़ती. सबसे ऊपर की लेयर का एलिमेंट, किसी भी एलिमेंट के ऊपर दिखता है. भले ही, उस एलिमेंट का z-index सबसे ज़्यादा हो.
टॉप लेयर को 'सबसे ऊपर स्टैक की गई लेयर' कहा जा सकता है. हर दस्तावेज़ में एक ही व्यूपोर्ट होता है. इसलिए, इसमें एक ही टॉप लेयर भी होती है. एक ही समय में, टॉप लेयर में कई एलिमेंट हो सकते हैं. ऐसा होने पर, वे एक-दूसरे के ऊपर स्टैक हो जाते हैं. आखिरी टैब सबसे ऊपर होता है. दूसरे शब्दों में, टॉप लेयर के सभी एलिमेंट को टॉप लेयर में आखिर में जोड़ा गया, पहले हटाया गया (एलआईएफ़ओ) स्टैक में रखा जाता है.
ब्राउज़र, <dialog>
एलिमेंट के अलावा, अन्य एलिमेंट को भी टॉप लेयर में रेंडर करता है. फ़िलहाल, टॉप लेयर के एलिमेंट ये हैं:
पॉपओवर, मॉडल डायलॉग, और फ़ुलस्क्रीन मोड में मौजूद एलिमेंट.
डायलॉग बॉक्स लागू करने के लिए, यहां दिया गया तरीका अपनाएं:
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
यहां कुछ डायलॉग का डेमो दिया गया है. इनके बैकड्रॉप पर स्टाइल लागू की गई हैं (बैकड्रॉप के बारे में नीचे बताया गया है):
बैकड्रॉप क्या है?
हालांकि, टॉप लेयर एलिमेंट के नीचे मौजूद कॉन्टेंट को पसंद के मुताबिक बनाने का एक तरीका है.
टॉप लेयर में मौजूद हर एलिमेंट में एक सीएसएस स्यूडो-एलिमेंट होता है, जिसे बैकड्रॉप कहा जाता है.
बैकड्रॉप, व्यूपोर्ट के साइज़ का एक बॉक्स होता है. इसे किसी भी टॉप लेयर एलिमेंट के ठीक नीचे रेंडर किया जाता है. ::backdrop
स्यूडो-एलिमेंट की मदद से, सबसे ऊपर वाली लेयर में सबसे ऊपर मौजूद एलिमेंट के नीचे मौजूद सभी चीज़ों को धुंधला किया जा सकता है, उनका स्टाइल बदला जा सकता है या उन्हें पूरी तरह से छिपाया जा सकता है.
एक से ज़्यादा एलिमेंट को मॉडल बनाने पर, ब्राउज़र सबसे सामने मौजूद ऐसे एलिमेंट के नीचे और फ़ुलस्क्रीन वाले दूसरे एलिमेंट के ऊपर बैकग्राउंड बनाता है.
बैकग्राउंड को स्टाइल करने का तरीका यहां बताया गया है:
/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
background: rgba(255,0,0,.25);
}
सिर्फ़ पहला बैकड्रॉप कैसे दिखाएं?
हर टॉप लेयर एलिमेंट का बैकग्राउंड, टॉप लेयर स्टैक से जुड़ा होता है. इन बैकग्राउंड को एक-दूसरे के ऊपर ओवरलैप करने के लिए डिज़ाइन किया गया है. इसलिए, अगर किसी बैकग्राउंड की ओपैसिटी 100% नहीं है, तो उसके नीचे मौजूद बैकग्राउंड दिखते हैं.
अगर आपको टॉप लेयर स्टैक में सिर्फ़ पहला बैकड्रॉप दिखाना है, तो टॉप लेयर स्टैक में आइटम आइडेंटिफ़ायर को ट्रैक करके ऐसा किया जा सकता है.
अगर जोड़ा गया एलिमेंट, टॉप लेयर में मौजूद पहला एलिमेंट नहीं है, तो एलिमेंट को टॉप लेयर में डालने पर कॉल किया जाने वाला फ़ंक्शन, ::backdrop
पर hiddenBackdrop
क्लास लागू करता है. जब एलिमेंट को टॉप लेयर से हटाया जाता है, तो यह क्लास हट जाती है.
इस उदाहरण के डेमो में कोड देखें:
DevTools में टॉप लेयर के लिए सहायता डिज़ाइन
टॉप लेयर के लिए DevTools की सहायता से, डेवलपर को टॉप लेयर के कॉन्सेप्ट को समझने और यह विज़ुअलाइज़ करने में मदद मिलती है कि टॉप लेयर का कॉन्टेंट कैसे बदलता है. इन सुविधाओं की मदद से, डेवलपर इन चीज़ों की पहचान कर सकते हैं:
- किसी भी समय टॉप लेयर में मौजूद एलिमेंट और उनका क्रम.
- स्टैक में किसी भी समय सबसे ऊपर मौजूद एलिमेंट.
इसके अलावा, DevTools की टॉप लेयर की सुविधा से, टॉप लेयर स्टैक में बैकग्राउंड के स्यूडो-एलिमेंट की पोज़िशन को विज़ुअलाइज़ करने में मदद मिलती है. हालांकि, यह ट्री एलिमेंट नहीं है, लेकिन यह टॉप लेयर के काम करने के तरीके में अहम भूमिका निभाता है. साथ ही, यह डेवलपर के लिए भी फ़ायदेमंद हो सकता है.
टॉप लेयर की सहायता सुविधाओं की मदद से, ये काम किए जा सकते हैं:
- देखें कि किसी भी समय टॉप लेयर स्टैक में कौनसे एलिमेंट मौजूद हैं. टॉप लेयर में एलिमेंट जोड़ने या हटाने पर, टॉप लेयर के स्टेटस का स्टैक डाइनैमिक तौर पर बदलता रहता है.
- सबसे ऊपर वाली लेयर के स्टैक में एलिमेंट की पोज़िशन देखें.
- ट्री में मौजूद टॉप लेयर एलिमेंट या एलिमेंट के बैकग्राउंड स्यूडो-एलिमेंट से, टॉप लेयर के प्रज़ेंटेशन कंटेनर में मौजूद एलिमेंट या बैकग्राउंड स्यूडो-एलिमेंट पर जाएं और फिर वापस आएं.
आइए, इन सुविधाओं को इस्तेमाल करने का तरीका जानें!
टॉप लेयर कंटेनर
टॉप लेयर के एलिमेंट को विज़ुअलाइज़ करने में मदद करने के लिए, DevTools, एलिमेंट ट्री में टॉप लेयर कंटेनर जोड़ता है. यह क्लोज़िंग </html>
टैग के बाद मौजूद होता है.
इस कंटेनर की मदद से, टॉप लेयर स्टैक में मौजूद एलिमेंट को कभी भी देखा जा सकता है. टॉप लेयर कंटेनर, टॉप लेयर एलिमेंट और उनके बैकड्रॉप के लिंक की सूची होती है. टॉप लेयर में एलिमेंट जोड़ने या हटाने पर, टॉप लेयर के स्टेटस का स्टैक डाइनैमिक तौर पर बदलता रहता है.
एलिमेंट ट्री या टॉप लेयर कंटेनर में टॉप लेयर एलिमेंट ढूंढने के लिए, टॉप लेयर कंटेनर में टॉप लेयर एलिमेंट के रेप्रज़ेंटेशन से एलिमेंट ट्री में उसी एलिमेंट पर और फिर से वापस जाने के लिए, लिंक पर क्लिक करें.
टॉप लेयर कंटेनर एलिमेंट से टॉप लेयर ट्री एलिमेंट पर जाने के लिए, टॉप लेयर कंटेनर में एलिमेंट के बगल में मौजूद दिखाएं बटन पर क्लिक करें.
टॉप लेयर ट्री एलिमेंट से टॉप लेयर कंटेनर में मौजूद लिंक पर जाने के लिए, एलिमेंट के बगल में मौजूद टॉप लेयर बैज पर क्लिक करें.
आपके पास किसी भी बैज को बंद करने का विकल्प होता है. इसमें टॉप लेयर वाला बैज भी शामिल है. बैज बंद करने के लिए, किसी भी बैज पर दायां क्लिक करें. इसके बाद, बैज की सेटिंग चुनें और उन बैज के बगल से सही का निशान हटाएं जिन्हें आपको छिपाना है.
टॉप लेयर स्टैक में एलिमेंट का क्रम
सबसे ऊपर मौजूद लेयर कंटेनर में, एलिमेंट वैसे ही दिखते हैं जैसे वे स्टैक में दिखते हैं. हालांकि, वे उलटे क्रम में दिखते हैं. स्टैक एलिमेंट सबसे ऊपर होता है और यह टॉप लेयर कंटेनर की एलिमेंट सूची में सबसे आखिर में होता है. इसका मतलब है कि टॉप लेयर कंटेनर की सूची में मौजूद आखिरी एलिमेंट वह एलिमेंट है जिसके साथ फ़िलहाल दस्तावेज़ में इंटरैक्ट किया जा सकता है.
ट्री एलिमेंट के बगल में मौजूद बैज से पता चलता है कि एलिमेंट सबसे ऊपरी लेयर में हैं या नहीं. साथ ही, इनमें स्टैक में किसी एलिमेंट की पोज़िशन नंबर भी शामिल होता है.
इस स्क्रीनशॉट में, सबसे ऊपर मौजूद लेयर स्टैक में दो एलिमेंट हैं. दूसरा एलिमेंट, स्टैक में सबसे ऊपर है. अगर दूसरा एलिमेंट हटाया जाता है, तो पहला एलिमेंट सबसे ऊपर चला जाता है.
टॉप लेयर कंटेनर में बैकड्रॉप
जैसा कि ऊपर बताया गया है, हर टॉप लेयर एलिमेंट में एक सीएसएस स्यूडो-एलिमेंट होता है, जिसे बैकड्रॉप कहा जाता है. इस एलिमेंट को स्टाइल किया जा सकता है. इसलिए, इसकी जांच करना और इसका रेप्रज़ेंटेशन देखना भी फ़ायदेमंद होता है.
एलिमेंट ट्री में, बैकड्रॉप एलिमेंट उस एलिमेंट के क्लोज़िंग टैग से पहले होता है जिससे वह जुड़ा होता है. हालांकि, टॉप लेयर कंटेनर में, बैकग्राउंड लिंक उस टॉप लेयर एलिमेंट के ठीक ऊपर दिखता है जिससे वह जुड़ा है.
डीओएम ट्री में बदलाव
ElementsTreeElement
, DevTools में अलग-अलग DOM ट्री एलिमेंट बनाने और उन्हें मैनेज करने के लिए ज़िम्मेदार क्लास है. हालांकि, टॉप लेयर कंटेनर लागू करने के लिए, यह क्लास काफ़ी नहीं थी.
टॉप लेयर कंटेनर को ट्री में नोड के तौर पर दिखाने के लिए, हमने एक नई क्लास जोड़ी है. यह क्लास, DevTools ट्री एलिमेंट नोड बनाती है. पहले, DevTools एलिमेंट ट्री बनाने वाली क्लास हर TreeElement
को DOMNode
से शुरू करती थी. यह एक ऐसी क्लास है जिसमें backendNodeId
और बैकएंड से जुड़ी अन्य प्रॉपर्टी होती हैं. backendNodeId
को बैकएंड पर असाइन किया जाता है.
टॉप लेयर कंटेनर नोड, जिसमें टॉप लेयर एलिमेंट के लिंक की सूची होती है. इसे सामान्य ट्री एलिमेंट नोड के तौर पर काम करना चाहिए. हालांकि, यह नोड 'असल' डीओएम नोड नहीं है और बैकएंड को टॉप लेयर कंटेनर नोड बनाने की ज़रूरत नहीं है.
टॉप लेयर को दिखाने वाला फ़्रंटएंड नोड बनाने के लिए, हमने एक नया फ़्रंटएंड नोड जोड़ा है. इसे DOMNode
के बिना बनाया गया है. यह टॉप लेयर कंटेनर एलिमेंट, पहला फ़्रंटएंड नोड है जिसमें DOMNode
नहीं है. इसका मतलब है कि यह सिर्फ़ फ़्रंटएंड पर मौजूद है और बैकएंड को इसके बारे में 'पता' नहीं है. अन्य नोड की तरह ही व्यवहार करने के लिए, हमने एक नई TopLayerContainer
क्लास बनाई है. यह क्लास, UI.TreeOutline.TreeElement
क्लास को बढ़ाती है, जो फ़्रंटएंड नोड के व्यवहार के लिए ज़िम्मेदार है.
अपनी पसंद के प्लेसमेंट को पाने के लिए, एलिमेंट को रेंडर करने वाली क्लास, TopLayerContainer
को <html>
टैग के अगले सिबलिंग के तौर पर अटैच करती है.
टॉप लेयर का नया बैज यह दिखाता है कि एलिमेंट टॉप लेयर में है. साथ ही, यह TopLayerContainer
एलिमेंट में इस एलिमेंट के शॉर्टकट के लिंक के तौर पर काम करता है.
शुरुआती डिज़ाइन
शुरुआत में, एलिमेंट के लिंक की सूची बनाने के बजाय, टॉप लेयर के एलिमेंट को टॉप लेयर कंटेनर में डुप्लीकेट करने का प्लान था. हमने यह तरीका लागू नहीं किया, क्योंकि DevTools में एलिमेंट के चाइल्ड को फ़ेच करने का तरीका अलग है. हर एलिमेंट में एक पैरंट पॉइंटर होता है, जिसका इस्तेमाल चाइल्ड एलिमेंट फ़ेच करने के लिए किया जाता है. साथ ही, एक से ज़्यादा पॉइंटर नहीं हो सकते. इसलिए, हमारे पास ऐसा कोई नोड नहीं हो सकता जो सही तरीके से बड़ा हो और ट्री में सभी चाइल्ड को कई जगहों पर दिखाता हो. आम तौर पर, सिस्टम को डुप्लीकेट सबट्री के हिसाब से नहीं बनाया गया था.
हमने इस समस्या को हल करने के लिए, फ़्रंटएंड DOM नोड को डुप्लीकेट करने के बजाय, उनके लिंक बनाए. DevTools में एलिमेंट के लिंक बनाने की ज़िम्मेदारी ShortcutTreeElement
क्लास की होती है. यह UI.TreeOutline.TreeElement
को एक्सटेंड करती है. ShortcutTreeElement
का व्यवहार, DevTools के अन्य DOM ट्री एलिमेंट जैसा ही होता है. हालांकि, बैकएंड पर इसका कोई नोड नहीं होता और इसमें एक बटन होता है जो ElementsTreeElement
से लिंक होता है.
टॉप लेयर नोड के हर ShortcutTreeElement
में एक चाइल्ड ShortcutTreeElement
होता है, जो DevTools के DOM ट्री में ::backdrop
स्यूडो-एलिमेंट के रेप्रज़ेंटेशन से जुड़ा होता है.
शुरुआती डिज़ाइन:
Chrome DevTools प्रोटोकॉल (सीडीपी) में हुए बदलाव
सबसे ऊपर की लेयर की सहायता लागू करने के लिए, Chrome DevTools प्रोटोकॉल (CDP) में बदलाव करना ज़रूरी है. CDP, DevTools और Chromium के बीच कम्यूनिकेशन प्रोटोकॉल के तौर पर काम करता है.
हमें यह जानकारी जोड़नी होगी:
- फ़्रंटएंड से किसी भी समय कॉल करने का निर्देश.
- बैकएंड से फ़्रंटएंड पर ट्रिगर होने वाला इवेंट.
सीडीपी: DOM.getTopLayerElements
कमांड
मौजूदा टॉप लेयर एलिमेंट दिखाने के लिए, हमें एक्सपेरिमेंट के तौर पर उपलब्ध CDP का एक नया निर्देश चाहिए. यह निर्देश, टॉप लेयर में मौजूद एलिमेंट के नोड आईडी की सूची दिखाता है. DevTools के खुलने या टॉप लेयर के एलिमेंट बदलने पर, DevTools इस निर्देश को कॉल करता है. यह निर्देश कुछ ऐसा दिखता है:
# Returns NodeIds of the current top layer elements.
# Top layer renders closest to the user within a viewport, therefore, its elements always
# appear on top of all other content.
experimental command getTopLayerElements
returns
# NodeIds of the top layer elements.
array of NodeId nodeIds
सीडीपी: DOM.topLayerElementsUpdated
इवेंट
टॉप लेयर एलिमेंट की अप-टू-डेट सूची पाने के लिए, हमें एक्सपेरिमेंटल सीडीपी इवेंट को ट्रिगर करने के लिए, टॉप लेयर एलिमेंट में होने वाले हर बदलाव की ज़रूरत होती है. यह इवेंट, फ़्रंटएंड को बदलाव के बारे में बताता है. इसके बाद, DOM.getTopLayerElements
कमांड को कॉल किया जाता है और नई एलिमेंट सूची मिलती है.
इवेंट कुछ ऐसा दिखता है:
# Called by the change of the top layer elements.
experimental event topLayerElementsUpdated
सीडीपी के बारे में जानकारी
टॉप लेयर के सीडीपी की सहायता को लागू करने के कई विकल्प थे. हमने एक और विकल्प पर भी विचार किया था. इसमें, एक ऐसा इवेंट बनाया जाता जो टॉप लेयर एलिमेंट के जोड़े या हटाए जाने के बारे में फ़्रंट एंड को बताने के बजाय, टॉप लेयर एलिमेंट की सूची दिखाता.
इसके अलावा, हम कमांड के बजाय दो इवेंट बना सकते हैं: topLayerElementAdded
और topLayerElementRemoved
. इस मामले में, हमें एक एलिमेंट मिलेगा और हमें फ़्रंट एंड पर टॉप लेयर एलिमेंट के कलेक्शन को मैनेज करना होगा.
फ़िलहाल, अपडेट किए गए एलिमेंट की सूची पाने के लिए, कोई फ़्रंटएंड इवेंट getTopLayerElements
कमांड को कॉल करता है. अगर हमें हर बार इवेंट ट्रिगर होने पर, उन एलिमेंट या किसी खास एलिमेंट की सूची भेजनी होती है जिसकी वजह से बदलाव हुआ है, तो कमांड को कॉल करने के एक चरण को छोड़ा जा सकता है.
हालांकि, इस मामले में फ़्रंटएंड के पास यह कंट्रोल नहीं होगा कि कौनसे एलिमेंट पुश किए जाएं.
हमने इसे इस तरह लागू किया है, क्योंकि हमारे हिसाब से यह बेहतर है कि टॉप लेयर नोड का अनुरोध करने का फ़ैसला फ़्रंटएंड ले. उदाहरण के लिए, अगर यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर की लेयर को छोटा किया गया है या उपयोगकर्ता ऐसे DevTools पैनल का इस्तेमाल कर रहा है जिसमें एलिमेंट ट्री नहीं है, तो ट्री में गहरे लेवल पर मौजूद अतिरिक्त नोड पाने की ज़रूरत नहीं है.