क्या आईडी के साथ डोम ट्री तत्व वैश्विक चर बन जाते हैं?


364

एक सरल HTMLElement रैपर के लिए एक आइडिया पर काम करना मैंने इंटरनेट एक्सप्लोरर और क्रोम के लिए निम्नलिखित पर ठोकर खाई :

DOM ट्री में ID के साथ दिए गए HTMLElement के लिए, अपनी ID का उपयोग चर नाम के रूप में करना संभव है। तो जैसे एक div के लिए

<div id="example">some text</div>

में इंटरनेट एक्सप्लोरर 8 और क्रोम आप कर सकते हैं:

alert(example.innerHTML); //=> 'some text'

या

alert(window['example'].innerHTML); //=> 'some text'

तो, क्या इसका मतलब है कि DOM ट्री में मौजूद हर तत्व ग्लोबल नेमस्पेस में एक वेरिएबल में बदल जाता है? और क्या इसका यह मतलब भी है कि कोई getElementByIdइन ब्राउज़रों में विधि के प्रतिस्थापन के रूप में इसका उपयोग कर सकता है?



1
@ बर्गी, टिप्पणी जो यह नहीं करने के लिए कहती है कि यह अब पुराना और अमान्य भी है। इसलिए, मुझे इस सुविधा का उपयोग नहीं करने का कोई ठोस कारण नहीं मिल रहा है।
ईएसआर

@EdmundReed आप लिंक किए गए प्रश्न के उत्तर को फिर से पढ़ना चाह सकते हैं - यह अभी भी एक बुरा विचार है: " निहित रूप से घोषित वैश्विक चर " बिना टूलींग समर्थन के खराब हैं और " भंगुर कोड की ओर ले जाते हैं "। इसे "सुविधा" न कहें, नीचे दिया गया उत्तर बताता है कि यह कैसे एक बग है जो संगतता कारणों के लिए मानक का हिस्सा बन गया है।
बरगी

1
@ बर्गी काफी, आप सही कह रहे हैं। मुझे अभी भी लगता है कि यह वास्तव में एक साफ सुथरा फीचर है, और इसे केवल समस्याग्रस्त माना जाता है क्योंकि लोग इसके बारे में जानते नहीं हैं। इस तरह से मैं इसका इस्तेमाल करने की कल्पना कर रहा हूं: codepen.io/esr360/pen/WEavGE?editors=1000#0
ESR

@EdmundReed यह कम समस्यापूर्ण है यदि आप पाठ्यक्रम की सामग्री और तर्क को ठीक से अलग नहीं करते हैं। इसके अलावा, मैं इनलाइन ईवेंट हैंडलर का उपयोग कभी नहीं करने की सलाह देता हूं या DOM तत्वों पर कस्टम तरीकों को स्थापित करने के लिए उन्हें नामस्थान के रूप में दुरुपयोग कर रहा हूं (ध्यान दें कि यह "गुंजाइश" नहीं है)।
बेर्गी

जवाबों:


395

माना जाता है कि 'नामित तत्व' documentवस्तु के स्पष्ट गुणों के रूप में जोड़े जाते हैं । यह एक बहुत बुरा विचार है, क्योंकि यह तत्व के नामों को वास्तविक गुणों के साथ टकराव करने की अनुमति देता है document

IE ने windowवस्तु के गुणों के रूप में नामित तत्वों को जोड़कर स्थिति को बदतर बना दिया । यह इस बात से दोगुना बुरा है कि अब आपको documentया तो के किसी भी सदस्य के बाद अपने तत्वों के नामकरण से बचना होगाwindow आपके या (आपके प्रोजेक्ट में कोई अन्य लाइब्रेरी कोड) ऑब्जेक्ट के ।

इसका मतलब यह भी है कि ये तत्व वैश्विक जैसे चर के रूप में दिखाई देते हैं। सौभाग्य से इस मामले में आपके कोड में कोई भी वास्तविक वैश्विक varया functionघोषणाएं छाया हुई हैं, इसलिए आपको यहां नामकरण के बारे में बहुत चिंता करने की आवश्यकता नहीं है, लेकिन यदि आप एक क्लैशिंग नाम के साथ एक वैश्विक चर के लिए एक असाइनमेंट करने की कोशिश करते हैं और आप घोषणा करना भूल जाते हैं यह var, आपको IE में एक त्रुटि मिलेगी क्योंकि यह तत्व को स्वयं को निर्दिष्ट करने का प्रयास करता है।

इसे आम तौर पर बुरा मानना ​​माना जाता है var, साथ ही windowग्लोबल्स पर या दिखाई दे रहे तत्वों पर भरोसा करना । स्टिक टू document.getElementById, जो अधिक व्यापक रूप से समर्थित और कम अस्पष्ट है। यदि आप टाइपिंग पसंद नहीं करते हैं, तो आप एक छोटे नाम के साथ एक तुच्छ आवरण फ़ंक्शन लिख सकते हैं। किसी भी तरह, आईडी-टू-एलिमेंट लुकअप कैश का उपयोग करने का कोई मतलब नहीं है, क्योंकि ब्राउज़र आमतौर पर getElementByIdत्वरित लुकअप का उपयोग करने के लिए कॉल का अनुकूलन करते हैं; जब आप तत्व बदलते हैं idया दस्तावेज़ से जोड़े / हटाए जाते हैं तो आपको सभी समस्याएं होती हैं।

ओपेरा की नकल की आईई, तो में शामिल हो गए वेबकिट, और पर नामित तत्वों डालने की अब दोनों पहले से unstandardised अभ्यास documentगुण, और उन पर डालने की पूर्व-IE-केवल अभ्यास windowकर रहे हैं किया जा रहा मानकीकृत एचटीएमएल 5, जिसका दृष्टिकोण दस्तावेज करने के लिए है और हर प्रमाण के द्वारा ब्राउज़र लेखकों द्वारा हमारे ऊपर भयंकर प्रथा, उन्हें हमेशा के लिए वेब का हिस्सा बना देती है। तो फ़ायरफ़ॉक्स 4 भी इस का समर्थन करेगा।

'नामित तत्व' क्या हैं? कुछ के साथ कुछ भी id, और name'की पहचान' प्रयोजनों के लिए इस्तेमाल किया जा रहा है के साथ कुछ भी : अर्थात्, रूपों, चित्र, एंकर और कुछ अन्य, लेकिन एक nameविशेषता के अन्य असंबंधित उदाहरण नहीं हैं , जैसे फार्म इनपुट फ़ील्ड में नियंत्रण-नाम, पैरामीटर नाम <param>या मेटाडेटा प्रकार में <meta>। 'पहचानने वाले' nameवे हैं जिनके पक्ष में जाने से बचना चाहिए id


5
यह एक स्पष्ट जवाब है, धन्यवाद। डॉक्युमेंट को भूल जाना मेरा विचार नहीं था ।getElementById (ठीक है, तथ्य की बात के रूप में मैं xpath का उपयोग करता हूं जहां आजकल तत्वों / तत्वों के गुणों को देखना संभव है)। मैं नामित वस्तुओं के लिए इस (बुरे) अभ्यास पर लड़खड़ा गया और उत्सुक था कि यह कहां से आया है। आपने उत्तर दिया कि पर्याप्त रूप से पर्याप्त है; अब हम जानते हैं कि यह क्रोम (वेबकिट) में भी क्यों पाया जा सकता है।
KooiInc

18
"उपयोग से nameबचा जाना चाहिए " के लिए एक अपवाद है <input>, जहां nameविशेषता फॉर्म सबमिशन के लिए कुंजी-मूल्य जोड़े की कुंजी बनाने में महत्वपूर्ण भूमिका निभाता है।
याहल

7
FYI करें फ़ायरफ़ॉक्स केवल यह करता है जब quirks मोड में डाल दिया।
वर्धमान ताजा

4
@ येल्हक: बिल्कुल यही भेद मैं बना रहा हूं। " nameफार्म इनपुट क्षेत्रों में नियंत्रण-नाम की तरह के अन्य उपयोग नहीं ..."
bobince

13
क्यों!? क्या इस पागलपन को रोकने के लिए हम कुछ कर सकते हैं? तत्वों के संदर्भ से मेरे कार्यों को फिर से परिभाषित किया गया और मुझे डिबग करने में एक घंटे का समय लगा। :(
फरजेर

52

जैसा कि पहले उत्तर में बताया गया है कि इस व्यवहार को विंडो ऑब्जेक्ट पर नामित पहुंच के रूप में जाना जाता है । का मान nameकुछ तत्वों के लिए विशेषता और मूल्य के idसभी तत्वों के लिए विशेषता वैश्विक के गुणों के रूप में उपलब्ध कराया जाता है windowवस्तु। इन्हें नामित तत्व के रूप में जाना जाता है। चूंकि windowब्राउज़र में वैश्विक ऑब्जेक्ट है, प्रत्येक नामित तत्व वैश्विक चर के रूप में सुलभ होगा।

यह मूल रूप से इंटरनेट एक्सप्लोरर द्वारा जोड़ा गया था और अंततः सभी अन्य ब्राउज़रों द्वारा उन साइटों के साथ संगतता के लिए लागू किया गया था जो इस व्यवहार पर निर्भर हैं। दिलचस्प बात यह है कि, गेको (फ़ायरफ़ॉक्स का रेंडरिंग इंजन) ने इसे क्वर्की मोड में ही लागू करने के लिए चुना , जबकि अन्य रेंडरिंग इंजन ने इसे मानक मोड में छोड़ दिया।

हालाँकि, फ़ायरफ़ॉक्स 14 के रूप में, फ़ायरफ़ॉक्स अबwindow मानक मोड में ऑब्जेक्ट पर नाम एक्सेस का समर्थन करता है । उन्होंने इसे क्यों बदला? पता चलता है कि अभी भी बहुत सारी साइटें हैं जो मानकों मोड में इस कार्यक्षमता पर निर्भर हैं। Microsoft ने एक मार्केटिंग डेमो भी जारी किया, जिसने डेमो को फ़ायरफ़ॉक्स में काम करने से रोक दिया।

वेबकिट ने हाल ही में विपरीत पर विचार किया है , windowऑब्जेक्ट पर नाम का उपयोग केवल quirks मोड तक पहुंच गया है । उन्होंने गेको के ही तर्क से इसके खिलाफ फैसला किया।

तो ... यह जैसा लगता है कि पागल है यह व्यवहार अब तकनीकी रूप से सभी प्रमुख ब्राउज़रों के नवीनतम संस्करण में मानक मोड में उपयोग करने के लिए सुरक्षित है । लेकिन नामित नाम कुछ सुविधाजनक लग सकता है, इसका उपयोग नहीं किया जाना चाहिए

क्यों? इस लेख में बहुत सारे तर्क दिए जा सकते हैं कि वैश्विक चर खराब क्यों हैं । सीधे शब्दों में कहें, अतिरिक्त वैश्विक चर का एक गुच्छा अधिक कीड़े की ओर जाता है। मान लीजिए कि आप गलती से एक का नाम टाइप करते हैं varऔर idएक DOM नोड, SURPRISE टाइप करते हैं !

इसके अतिरिक्त, मानकीकृत होने के बावजूद भी ब्राउज़र की नामित पहुंच के कार्यान्वयन में काफी विसंगतियां हैं।

  • IE गलत तरीके से nameफॉर्म तत्वों (इनपुट, चयन, आदि) के लिए विशेषता के मूल्य को सुलभ बनाता है।
  • गेको और वेबकिट गलत तरीके <a>से टैग को अपनी nameविशेषता के माध्यम से सुलभ नहीं बनाते हैं ।
  • गेको गलत तरीके से एक ही नाम के साथ कई नामित तत्वों को संभालता है (यह एक संदर्भ के बजाय एक एकल नोड का संदर्भ देता है)।

और मुझे यकीन है कि यदि आप किनारे के मामलों में उपयोग किए गए नाम का उपयोग करने की कोशिश कर रहे हैं तो यह अधिक है।

जैसा कि अन्य उत्तरों में बताया गया है document.getElementByIdकि इसके द्वारा DOM नोड का संदर्भ प्राप्त करने के लिए उपयोग किया जाता है id। यदि आपको इसके nameविशेषता उपयोग द्वारा नोड का संदर्भ प्राप्त करने की आवश्यकता है document.querySelectorAll

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

यदि आप रुचि रखते हैं, तो मैं इस बारे में अपने ब्लॉग पर और अधिक विस्तार से बात करता हूं - https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/


3
केवल स्पष्ट चेतावनी के आधार पर एक टिप्पणी कि "इसका उपयोग नहीं किया जाना चाहिए"। यही है, "यह उपयोग नहीं किया जाना चाहिए UNLESS आप एक कोड चरवाहे हो।" कोड काउबॉय सिर्फ इसके लिए जाते हैं।
जेरेमी फोस्टर

5
@jeremyfoster जब तक कि "कोड काउबॉय" का अर्थ किसी ऐसे व्यक्ति से नहीं है जो बुरे डेवलपर-अमित्रों के कार्यान्वयन का उपयोग करता है और प्रचार करता है, मैं दृढ़ता से असहमत हूं।
पैट्रिक रॉबर्ट्स

2
एक अच्छे चरवाहे का एक निशान यह है कि कई असहमत हैं। लेकिन अब मैं दार्शनिक चरवाहे की तरह हूं या ऐसा कुछ।
जेरेमी फोस्टर

अधिक लोगों का उपयोग करना चाहिए document.querySelectorAllऔर document.querySelectorजब डोम तक पहुँचने। उस के अच्छे सुझाव के लिए +1। चयनकर्ता द्वारा तत्वों को एक्सेस करना निश्चित रूप से एक अधिक कुशल प्रक्रिया है।
ट्रैविस जे

20

आपको getElementById()इन मामलों में रहना चाहिए , उदाहरण के लिए:

document.getElementById('example').innerHTML

IE वैश्विक नाम स्थान में तत्वों name और ID विशेषताओं के साथ मिश्रण करना पसंद करता है , इसलिए आप जो पाने की कोशिश कर रहे हैं उसके बारे में स्पष्ट होना सबसे अच्छा है।


3

हाँ, वो करते हैं।


निम्न उदाहरण के साथ क्रोम 55, फ़ायरफ़ॉक्स 50, आईई 11, आईई एज 14 और सफारी 10 में परीक्षण किया गया:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="im_not_particularly_happy_with_that">
    Hello World!
  </div>
  <script>
    im_not_particularly_happy_with_that.innerText = 'Hello Internet!';
  </script>
  <!-- Looking at you W3 HTML5 spec group _ -->
</body>
</html>

http://jsbin.com/mahobinopa/edit?html,output


1
ओपेरा में भी। हालांकि, मुझे लगता है कि इस पृष्ठ पर व्यक्त इस तंत्र पर आपत्ति बहुत अच्छी तरह से ली गई है।
ncmathsadist

1

सवाल ध्वनि होना चाहिए: "क्या HTML टैग प्रदान की गई आईडी के साथ विश्व स्तर पर सुलभ DOM एलीमेंट बन गए हैं?"

इसका जवाब है हाँ!

यह काम करने के लिए कैसे किया गया था, और यही कारण है कि आईडी को W3C द्वारा शुरू करने के लिए पेश किया गया था।: एक पार्स स्क्रिप्टिंग वातावरण में एक HTML टैग की आईडी इसकी संबंधित DOM तत्व संभाल बन जाती है।

हालाँकि, नेटस्केप मोज़िला ने W3C के अनुरूप (उन्हें घुसपैठ करने के लिए) मना कर दिया और हठ पैदा करने के लिए पदावनत नाम विशेषता का उपयोग करते रहे और इसलिए स्क्रिप्टिंग की कार्यक्षमता और W3C की विशिष्ट ID द्वारा पेश की गई कोडिंग सुविधा को तोड़ दिया।

नेटस्केप नेविगेटर 4.7 के बाद उनके डेवलपर्स ने सभी को जाना और W3C में घुसपैठ की, जबकि उनके सहयोगी गलत प्रथाओं और गलत उदाहरणों के साथ वेब पर कब्जा कर रहे थे। आईडी विशेषताओं के साथ सममूल्य पर [पहले से हटाए गए नाम विशेषता [! जो अद्वितीय होने का मतलब नहीं था] का उपयोग और पुन: उपयोग के लिए मजबूर करना ताकि स्क्रिप्ट जो विशेष डोम तत्वों तक पहुंचने के लिए आईडी हैंडल का उपयोग करती है, वह बस टूट जाएगी!

और तोड़ उन्होंने किया क्योंकि वे भी लिख सकते हैं और व्यापक कोडिंग सबक और उदाहरण के रूप में [अपने ब्राउज़र वैसे भी पहचान नहीं सकेंगे] प्रकाशित करेंगे document.all.ElementID.propertyबजाय ElementID.propertyकम से कम करने के लिए इसे अक्षम कर सकते हैं और यह बस पर यह नहीं तोड़ा मामले में और अधिक भूमि के ऊपर ब्राउज़र देना HTML डोमेन (अब [1996-97], पदावनत) के लिए एक ही टोकन का उपयोग करके नाम और मानक आईडी विशेषता समान टोकन मूल्य के साथ इसकी आपूर्ति करता है।

वे आसानी से अज्ञानी कोड-लेखन के शौकीनों की भारी सेना को समझाने में कामयाब रहे कि नाम और आईडी व्यावहारिक रूप से समान हैं, सिवाय इसके कि आईडी विशेषता छोटी है और इसलिए बाइट-सेविंग और प्राचीन नाम संपत्ति की तुलना में कोडर के लिए अधिक सुविधाजनक है। जो निश्चित ही झूठ था। या - HTML के उनके प्रकाशित लेखों में, उन लेखों को समझाने के लिए, जिन्हें आपको स्क्रिप्टिंग इंजन द्वारा सुलभ होने के लिए अपने टैग को नाम और आईडी दोनों प्रदान करने की आवश्यकता होगी।

मोज़ेक हत्यारों [कोडनाम "मोज़िला"] को इतना परेशान किया गया कि उन्होंने सोचा "अगर हम नीचे जाते हैं, तो इंटरनेट चाहिए"।

बढ़ती Microsoft - दूसरी ओर - इतने भोले थे कि उन्हें लगता है कि उन्हें हटाए जाने और हटाने के लिए चिह्नित किया जाना चाहिए नाम संपत्ति और इसे मानो कि यह एक आईडी थी जो एक अद्वितीय पहचानकर्ता है ताकि वे स्क्रिप्टिंग की कार्यक्षमता को न तोड़ें नेटस्केप प्रशिक्षुओं द्वारा कोड किए गए पुराने पृष्ठ। वे घातक गलत थे ...

और आईडी परस्पर विरोधी तत्वों के एक सरणी संग्रह की वापसी इस जानबूझकर मानव निर्मित समस्या का समाधान नहीं थी। वास्तव में इसने पूरे उद्देश्य को हरा दिया।

और यही एकमात्र कारण है कि W3C बदसूरत हो गया और हमें मूर्खताएँ दीं जैसे कि document.getElementByIdऔर साथ में रूडोको गोड्डामन कष्टप्रद सिंटैक्स की तरह ... (...)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.