क्या आप जानते हैं कि वैश्विक चर के रूप में जावास्क्रिप्ट में आईडी वाले डीओएम तत्वों को एक्सेस किया जा सकता है? यह उन चीजों में से एक है, जैसे, हमेशा के लिए, लेकिन मैं वास्तव में पहली बार इसमें खुदाई कर रहा हूं।
अगर आप इसके बारे में पहली बार सुन रहे हैं, तो अपने आप को संभाल लें! हम इसे केवल HTML में किसी तत्व में एक आईडी जोड़कर क्रिया में देख सकते हैं:
आम तौर पर, हम एक नए चर का उपयोग करके परिभाषित करेंगे querySelector("#cool")
or getElementById("cool")
उस तत्व का चयन करने के लिए:
var el = querySelector("#cool");
लेकिन वास्तव में हमारे पास पहले से ही पहुंच है #cool
उस रिगामोरेल के बिना:
तो, कोई भी id
- या name
विशेषता, उस मामले के लिए - HTML में जावास्क्रिप्ट का उपयोग करके पहुँचा जा सकता है window[ELEMENT_ID]
. फिर, यह बिल्कुल "नया" नहीं है, लेकिन यह देखना वास्तव में असामान्य है।
जैसा कि आप अनुमान लगा सकते हैं, नामित संदर्भों के साथ वैश्विक दायरे तक पहुंचना सबसे बड़ा विचार नहीं है। कुछ लोग इसे "वैश्विक दायरा प्रदूषक" कहने आए हैं। हम इसमें शामिल होंगे कि ऐसा क्यों है, लेकिन पहले…
कुछ प्रसंग
यह दृष्टिकोण है HTML विनिर्देश में उल्लिखित, जहां इसे "इस पर नामित पहुंच" के रूप में वर्णित किया गया है Window
वस्तु।"
इंटरनेट एक्सप्लोरर इस सुविधा को लागू करने वाला पहला व्यक्ति था। अन्य सभी ब्राउज़रों ने इसे भी जोड़ा। उस समय गेको एकमात्र ऐसा ब्राउज़र था जो सीधे मानक मोड में इसका समर्थन नहीं करता था, इसके बजाय इसे एक प्रयोगात्मक सुविधा बनाने के लिए चुना गया था। इसे लागू करने में बिल्कुल झिझक थी, लेकिन यह ब्राउज़र संगतता के नाम पर आगे बढ़े (गेको ने भी करने की कोशिश की वेबकिट को मनाएं इसे मानक मोड से बाहर ले जाने के लिए) और अंततः इसे फ़ायरफ़ॉक्स 14 में मानक मोड में बना दिया।
एक बात जो अच्छी तरह से ज्ञात नहीं हो सकती है, वह यह है कि ब्राउज़रों को कुछ एहतियाती उपाय करने पड़ते हैं - सफलता की अलग-अलग डिग्री के साथ - यह सुनिश्चित करने के लिए कि उत्पन्न ग्लोबल्स वेबपेज को न तोड़ें। ऐसा ही एक उपाय है…
चर छायांकन
शायद इस विशेषता का सबसे दिलचस्प हिस्सा यह है कि नामित तत्व संदर्भ नहीं हैं छाया मौजूदा वैश्विक चर. इसलिए, यदि किसी DOM तत्व में a . है id
जिसे पहले से ही वैश्विक के रूप में परिभाषित किया गया है, यह मौजूदा को ओवरराइड नहीं करेगा। उदाहरण के लिए:
window.foo = "bar";
I won't override window.foo
console.log(window.foo); // Prints "bar"
और इसके विपरीत भी सच है:
I will be overridden :(
window.foo = "bar";
console.log(window.foo); // Prints "bar"
यह व्यवहार आवश्यक है क्योंकि यह खतरनाक ओवरराइड्स को समाप्त करता है जैसे
, जो अन्यथा अमान्य करके एक विरोध पैदा करेगा alert
एपीआई। यह सुरक्षा तकनीक बहुत अच्छी तरह से हो सकती है कि आप - यदि आप मेरे जैसे हैं - पहली बार इसके बारे में सीख रहे हैं।
नामित ग्लोबल्स के खिलाफ मामला
इससे पहले, मैंने कहा था कि वैश्विक नामित तत्वों को संदर्भ के रूप में उपयोग करना सबसे बड़ा विचार नहीं हो सकता है। इसके बहुत से कारण हैं, जो TJ VanToll ने अपने ब्लॉग पर अच्छी तरह से कवर किया है और मैं यहां संक्षेप में बताऊंगा:
- यदि डोम बदलता है, तो संदर्भ भी बदलता है। यह वास्तव में कुछ "भंगुर" बनाता है (विशिष्टता की अवधि इसके लिए) कोड जहां एचटीएमएल और जावास्क्रिप्ट के बीच चिंताओं का अलगाव बहुत अधिक हो सकता है।
- आकस्मिक संदर्भ बहुत आसान हैं। एक साधारण टाइपो बहुत अच्छी तरह से एक नामित वैश्विक को संदर्भित कर सकता है और आपको अप्रत्याशित परिणाम दे सकता है।
- इसे ब्राउज़र में अलग तरह से लागू किया जाता है। उदाहरण के लिए, हमें एक एंकर के साथ एक एंकर तक पहुंचने में सक्षम होना चाहिए
id
- जैसे- लेकिन कुछ ब्राउज़र (अर्थात् सफारी और फ़ायरफ़ॉक्स) वापस लौटते हैं
ReferenceError
कंसोल में। - हो सकता है कि यह आपके विचार से वापस न आए। युक्ति के अनुसार, जब डोम में एक ही नामित तत्व के कई उदाहरण होते हैं - कहते हैं, दो उदाहरण
— ब्राउज़र को वापस लौटना चाहिए
HTMLCollection
उदाहरणों की एक सरणी के साथ। हालाँकि, फ़ायरफ़ॉक्स केवल पहला उदाहरण देता है। तो फिर, युक्ति कहती है हमें an . के एक उदाहरण का उपयोग करना चाहिएid
किसी तत्व के पेड़ में वैसे भी। लेकिन ऐसा करने से कोई पेज काम करने से नहीं रुकेगा या ऐसा कुछ भी नहीं होगा। - शायद कोई प्रदर्शन लागत है? मेरा मतलब है, ब्राउज़र को संदर्भों की वह सूची बनानी होगी और उसे बनाए रखना होगा। कुछ लोगों ने परीक्षण चलाया इस स्टैक ओवरफ्लो थ्रेड में, जहां नामित ग्लोबल्स वास्तव में थे एक परीक्षण में अधिक प्रदर्शन करने वाला और हाल के एक परीक्षण में कम प्रदर्शन करने वाला.
अतिरिक्त मुद्दो पर विचार करना
आइए मान लें कि हम नामित ग्लोबल्स का उपयोग करने के खिलाफ आलोचनाओं को दूर करते हैं और वैसे भी उनका उपयोग करते हैं। यह सब अच्छा है। लेकिन कुछ चीजें हैं जिन पर आप विचार करना चाहेंगे जैसे आप करते हैं।
पॉलीफिल्स
जैसा कि एज-केस-वाई लग सकता है, इस प्रकार की वैश्विक जांच पॉलीफ़िल के लिए एक विशिष्ट सेटअप आवश्यकता है। निम्नलिखित उदाहरण देखें जहां हम नए का उपयोग करके कुकी सेट करते हैं CookieStore
API, इसे उन ब्राउज़र पर पॉलीफ़िल करना जो अभी तक इसका समर्थन नहीं करते हैं:
// Polyfill the CookieStore API if not yet implemented.
// https://developer.mozilla.org/en-US/docs/Web/API/CookieStore
if (!window.cookieStore) {
window.cookieStore = myCookieStorePolyfill;
}
cookieStore.set("foo", "bar");
यह कोड क्रोम में पूरी तरह से ठीक काम करता है, लेकिन सफारी में निम्न त्रुटि फेंकता है।
TypeError: cookieStore.set is not a function
सफारी के लिए समर्थन की कमी है CookieStore
इस लेखन के रूप में एपीआई। परिणामस्वरूप, पॉलीफ़िल लागू नहीं किया जाता है क्योंकि img
तत्व आईडी एक वैश्विक चर बनाता है जो के साथ संघर्ष करता है cookieStore
वैश्विक।
जावास्क्रिप्ट एपीआई अपडेट
हम स्थिति को बदल सकते हैं और एक और मुद्दा ढूंढ सकते हैं जहां ब्राउज़र के जावास्क्रिप्ट इंजन के अपडेट नामित तत्व के वैश्विक संदर्भों को तोड़ सकते हैं।
उदाहरण के लिए:
window.BarcodeDetector.focus();
वह स्क्रिप्ट इनपुट तत्व के संदर्भ को पकड़ लेती है और आमंत्रित करती है focus()
इस पर। यह सही ढंग से काम करता है। फिर भी, हम नहीं जानते कि कैसे लंबा यह काम करना जारी रखेगा।
आप देखिए, जिस वैश्विक चर का उपयोग हम इनपुट तत्व को संदर्भित करने के लिए कर रहे हैं, जैसे ही ब्राउज़र इसका समर्थन करना शुरू करेंगे, काम करना बंद कर देंगे BarcodeDetector
API. उस समय, window.BarcodeDetector
वैश्विक अब इनपुट तत्व का संदर्भ नहीं होगा और .focus()
फेंक देंगे "window.BarcodeDetector.focus
एक फ़ंक्शन नहीं है" त्रुटि।
बोनस: सभी नामित तत्व वैश्विक संदर्भ उत्पन्न नहीं करते हैं
कुछ मजेदार सुनना चाहते हैं? चोट के अपमान को जोड़ने के लिए, नामित तत्व वैश्विक चर के रूप में केवल तभी पहुंच योग्य होते हैं जब नामों में अक्षर के अलावा कुछ भी नहीं होता है। ब्राउज़र ऐसे आईडी वाले तत्व के लिए वैश्विक संदर्भ नहीं बनाएंगे जिसमें विशेष वर्ण और संख्याएं हों, जैसे hello-world
और item1
.
निष्कर्ष
आइए संक्षेप करें कि हम यहां कैसे पहुंचे:
- सभी प्रमुख ब्राउज़र स्वचालित रूप से प्रत्येक DOM तत्व के लिए वैश्विक संदर्भ बनाते हैं a
id
(या, कुछ मामलों में, aname
विशेषता)। - इन तत्वों को उनके वैश्विक संदर्भों के माध्यम से एक्सेस करना अविश्वसनीय और संभावित रूप से खतरनाक है। प्रयोग करना
querySelector
orgetElementById
बजाय. - चूंकि वैश्विक संदर्भ स्वचालित रूप से उत्पन्न होते हैं, इसलिए आपके कोड पर उनके कुछ दुष्प्रभाव हो सकते हैं। इसका उपयोग करने से बचने का यह एक अच्छा कारण है
id
विशेषता जब तक आपको वास्तव में इसकी आवश्यकता न हो।
दिन के अंत में, जावास्क्रिप्ट में नामित ग्लोबल्स का उपयोग करने से बचना शायद एक अच्छा विचार है। मैंने पहले इस बारे में कल्पना का हवाला दिया था कि यह कैसे "भंगुर" कोड की ओर जाता है, लेकिन यहां बिंदु घर चलाने के लिए पूरा पाठ है:
एक सामान्य नियम के रूप में, इस पर भरोसा करने से भंगुर कोड हो जाएगा। उदाहरण के लिए, वेब प्लेटफ़ॉर्म में नई सुविधाओं को जोड़े जाने के कारण, इस API के लिए कौन सी आईडी अंत में मैपिंग करती हैं, यह समय के साथ भिन्न हो सकती हैं। इसके बजाय, उपयोग करें
document.getElementById()
ordocument.querySelector()
.
मुझे लगता है कि यह तथ्य कि HTML युक्ति स्वयं इस सुविधा से दूर रहने की अनुशंसा करती है, स्वयं के लिए बोलती है।