क्वेरीसेलेक्टर और क्वेरी


165

मुझे पता है कि वास्तव में के बीच अंतर क्या है चाहते हैं querySelectorऔर querySelectorAllके खिलाफ getElementsByClassNameऔर getElementById?

से इस लिंक मैं इकट्ठा कर सकता है के साथ कि querySelectorमैं लिख सकता है document.querySelector(".myclass")वर्ग के साथ तत्व प्राप्त करने के लिए myclassऔर document.querySelector("#myid")आईडी के साथ तत्व प्राप्त करने के लिए myid। लेकिन मैं पहले से ही ऐसा कर सकते हैं getElementsByClassNameऔर getElementById। कौन सा पसंद किया जाना चाहिए?

इसके अलावा मैं XPages में काम करता हूं जहां ID गतिशील रूप से कोलन के साथ उत्पन्न होता है और इस तरह दिखता है view:_id1:inputText1। इसलिए जब मैं लिखता हूं तो document.querySelector("#view:_id1:inputText1")यह काम नहीं करता है। लेकिन लेखन document.getElementById("view:_id1:inputText1")कार्य करता है। कोई विचार क्यों?


1
querySelector का उपयोग HTML DOM ट्री को क्वेरी करने के लिए किया जाता है जिसमें html एलिमेंट और उसके गुण क्वेरी के लिए प्रमुख तत्व के रूप में शामिल हो सकते हैं ... आप इसे प्राप्त करने के लिए रेगुलर एक्सप्रेशन का उपयोग कर सकते हैं .. dojo.query () वही करता है
anix

1
क्या आपका मतलब नहीं है document.querySelectorAll(".myclass")? उपयोग करने document.querySelector(".myclass")से केवल पहला तत्व वापस आएगा जो मेल खाता है।
mhatch

जवाबों:


113

मैं जानना चाहूंगा कि वास्तव में getElementsByClassName और getElementById के मुकाबले क्वेरीसेलेक्टर और क्वेरीसेलर के बीच क्या अंतर है?

सिंटैक्स और ब्राउज़र समर्थन करते हैं।

querySelector अधिक उपयोगी है जब आप अधिक जटिल चयनकर्ताओं का उपयोग करना चाहते हैं।

उदाहरण के लिए सभी सूची आइटम एक तत्व से उतारे गए हैं जो कि फू वर्ग का सदस्य है: .foo li

document.querySelector ("# view: _id1: inputText1") यह काम नहीं करता है। लेकिन डॉक्यूमेंट लिखना ।getElementById ("दृश्य: _id1: inputText1") काम करता है। कोई विचार क्यों?

:चरित्र एक चयनकर्ता के अंदर विशेष अर्थ नहीं है। आपको इससे बचना होगा। (चयनकर्ता भागने चरित्र भी तो तुम से बचने के लिए एक जे एस स्ट्रिंग में विशेष अर्थ नहीं है, कि भी)।

document.querySelector("#view\\:_id1\\:inputText1")

3
यह ब्राउज़र से ब्राउज़र (और संस्करण से संस्करण तक) में भिन्न होगा। मुझे लगता है कि चयनकर्ता आधारित अधिक महंगे थे (लेकिन एक तरह से जो कभी भी महत्वपूर्ण होने की संभावना नहीं होगी)
क्वेंटिन

1
मैं @ जनसत्ता के बयान का समर्थन करता हूं। साइट आज भी डाउन है।
18

6
और वर्ग चयन के बारे में jsperf.com/getelementsbyclassname-vs-queryselectorall/25 भी देखें । निष्कर्ष: एक और अधिक होना चाहिए jquery की तुलना में शुद्ध जावास्क्रिप्ट, और विशिष्ट कार्य getElementByIdऔर getElementsByClassName। ClassName का चयन बिना कुछ सौ गुना धीमा हो सकता है getElementsByClassName
अतरहास

101

मोज़िला प्रलेखन से संग्रह :

NodeSelector इंटरफ़ेस यह विनिर्देश दस्तावेज़ को लागू करने वाले किसी भी ऑब्जेक्ट में दो नए तरीके जोड़ता है, DocumentFragment, या तत्व इंटरफेस:

querySelector

नोड के उपशीर्षक के भीतर पहला मिलान तत्व नोड लौटाता है । यदि कोई मिलान नोड नहीं मिला है, तो नल वापस आ गया है।

querySelectorAll

यदि कोई मिलान नहीं मिलता है, तो नोड के सबट्री के भीतर सभी मिलान तत्व नोड्स, या एक खाली नोडोडिस्ट युक्त एक नोडलिस्ट लौटाता है ।

तथा

नोट: द्वारा दिया गया नोडलिस्ट querySelectorAll()लाइव नहीं है, जिसका अर्थ है कि डीओएम में परिवर्तन संग्रह में परिलक्षित नहीं होते हैं। यह अन्य डोम क्वेरी तरीकों से अलग है जो लाइव नोड सूचियों को वापस करते हैं।


32
लाइव नोड सूची भेद को इंगित करने के लिए +1। आप परिणामों का उपयोग कैसे करना चाहते हैं, इस पर निर्भर रहने के लिए यह एक अत्यंत महत्वपूर्ण अंतर है।
जंबो पियानो

7
"लाइव" का मतलब है कि डोम रनटाइम में नोड जोड़ा गया है और उस न्यूली जोड़ा नोड पर काम कर सकता है
diEcho

83

अंतर के बारे में, वहाँ के बीच परिणामों में एक महत्वपूर्ण एक है querySelectorAllऔर getElementsByClassName: वापसी मान अलग है। querySelectorAllएक स्थिर संग्रह getElementsByClassNameलौटाएगा , जबकि एक जीवित संग्रह लौटाएगा। यदि आप परिणामों को बाद के उपयोग के लिए किसी चर में संग्रहीत करते हैं, तो यह भ्रम पैदा कर सकता है:

  • एक चर के साथ querySelectorAllउस तत्व को शामिल किया जाएगा जो उस समय चयनकर्ता को पूरा करता है जिसे विधि कहा जाता था
  • एक चर के साथ उत्पन्न getElementsByClassNameतत्वों में चयनकर्ता को पूरा करने वाले तत्व शामिल होंगे जब इसका उपयोग किया जाता है (यह उस क्षण से अलग हो सकता है जिसे विधि कहा जाता था)।

उदाहरण के लिए, नोटिस कैसे भले ही आप चर पुन: असाइन नहीं किया है aux1और aux2, वे विभिन्न मूल्यों वर्गों को अद्यतन करने के बाद होते हैं:

// storing all the elements with class "blue" using the two methods
var aux1 = document.querySelectorAll(".blue");
var aux2 = document.getElementsByClassName("blue");

// write the number of elements in each array (values match)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);

// change one element's class to "blue"
document.getElementById("div1").className = "blue";

// write the number of elements in each array (values differ)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);
.red { color:red; }
.green { color:green; }
.blue { color:blue; }
<div id="div0" class="blue">Blue</div>
<div id="div1" class="red">Red</div>
<div id="div2" class="green">Green</div>


2
बस उल्लेख करने के लिए - सभी पुराने DOM एप एक नोड सूची को वापस कर रहे हैं document.getElementsByName, document.getElementsByTagNameNSया document.getElementsByTagNameउसी व्यवहार को प्रदर्शित करेंगे।
आरबीटी

2
कुछ विश्लेषण कहते हैं कि querySelector getElementById से अधिक समय लेता है, जैसे यहाँ dimlucas.com/index.php/2016/09/17/… । यदि हम खाते में पहुंच समय लेते हैं तो क्या होगा? क्या getElementById से प्राप्त लाइव नोड क्वेरीसेंटर से स्थिर एक से अधिक समय लेता है?
एरिक

1
@RBT मैं उल्लेख करूंगा कि ये पुराने DOM APIs NodeList ऑब्जेक्ट नहीं लौटाते हैं, वे HTMLCollections लौटाते हैं।
मेन्स्ट्रिांट

@ एरिक document.getElementById()लाइव नोड वापस नहीं करता है। यह document.querySelector('#id_here')शायद अधिक तेज़ है क्योंकि querySelectorपहले सीएसएस चयनकर्ता को पार्स करना होगा।
मिस्रीट्रेंट

68

इस उत्तर के लिए, मैं का उल्लेख querySelectorऔर querySelectorAllquerySelector के रूप में * और करने के लिए getElementById, getElementsByClassName, getElementsByTagName, और getElementsByNamegetElement के रूप में *।

मुख्य अंतर

  1. querySelector * अधिक लचीला है, क्योंकि आप इसे किसी भी CSS3 चयनकर्ता को पारित कर सकते हैं, न कि केवल आईडी, टैग या कक्षा के लिए सरल।
  2. DOM के आकार के साथ querySelector का प्रदर्शन बदल जाता है जिस पर इसे लागू किया जाता है। * सटीक होने के लिए, querySelector * O (n) समय में चलने वाली कॉल और getElement * कॉल O (1) समय में चलती है, जहाँ n उस तत्व या दस्तावेज़ के सभी बच्चों की कुल संख्या है जिस पर इसे लागू किया जाता है। यह तथ्य कम से कम अच्छी तरह से जाना जाता है, इसलिए मैं इसे काट रहा हूं।
  3. getElement * कॉल DOM के लिए सीधे संदर्भ लौटाता है, जबकि querySelector * आंतरिक रूप से चयनित संदर्भों की प्रतियां उनके संदर्भ में लौटने से पहले बनाता है। इन्हें "लाइव" और "स्टैटिक" तत्वों के रूप में जाना जाता है। यह कड़ाई से संबंधित नहीं है कि वे किस प्रकार से लौटते हैं। यह बताने का कोई तरीका नहीं है कि मैं किसी तत्व को लाइव या स्टेटिक रूप से प्रोग्राम करता हूं, क्योंकि यह इस बात पर निर्भर करता है कि तत्व को किसी बिंदु पर कॉपी किया गया था या नहीं और यह डेटा की आंतरिक संपत्ति नहीं है। लाइव तत्वों में परिवर्तन तुरंत लागू होते हैं - एक जीवित तत्व को बदलने से यह सीधे DOM में बदल जाता है, और इसलिए JS की अगली पंक्ति उस परिवर्तन को देख सकती है, और यह उस तत्व को संदर्भित करने वाले किसी अन्य लाइव तत्व को तुरंत प्रसारित करता है। वर्तमान स्क्रिप्ट को निष्पादित करने के बाद स्थैतिक तत्वों में परिवर्तन केवल DOM पर वापस लिखा जाता है।
  4. इन कॉलों का रिटर्न प्रकार भिन्न होता है। querySelectorऔर getElementByIdदोनों एक ही तत्व को लौटाते हैं। querySelectorAllऔर getElementsByNameHTMLCollection के फैशन से बाहर हो जाने के बाद, नए फ़ंक्शन होने के नाते, दोनों NodeLists को लौटाते हैं। पुराने getElementsByClassNameऔर getElementsByTagNameदोनों HTMLCollections लौटाते हैं। फिर, यह अनिवार्य रूप से अप्रासंगिक है कि क्या तत्व जीवित हैं या स्थिर हैं।

इन अवधारणाओं को निम्नलिखित तालिका में संक्षेपित किया गया है।

Function               | Live? | Type           | Time Complexity
querySelector          |   N   | Element        |  O(n)
querySelectorAll       |   N   | NodeList       |  O(n)
getElementById         |   Y   | Element        |  O(1)
getElementsByClassName |   Y   | HTMLCollection |  O(1)
getElementsByTagName   |   Y   | HTMLCollection |  O(1)
getElementsByName      |   Y   | NodeList       |  O(1)

विवरण, टिप्स, और उदाहरण

  • HTMLCollections, NodeLists की तरह सरणी के समान नहीं हैं और .forEach () का समर्थन नहीं करते हैं। मुझे लगता है कि इस के आसपास काम करने के लिए उपयोगी प्रसार ऑपरेटर:

    [...document.getElementsByClassName("someClass")].forEach()

  • प्रत्येक तत्व और वैश्विक document, को छोड़कर इन सभी कार्यों के लिए उपयोग किया जाता है getElementByIdऔर getElementsByName, जिन्हें केवल लागू किया जाता है document

  • चेनिंग गेटईमेंट * क्वेरीस्लेक्टर * का उपयोग करने के बजाय कॉल * प्रदर्शन में सुधार करेगा, खासकर बहुत बड़े डोम पर। यहां तक ​​कि छोटे डोम और / या बहुत लंबी श्रृंखलाओं के साथ, यह आमतौर पर तेज होता है। हालाँकि, जब तक आप जानते हैं कि आपको प्रदर्शन की आवश्यकता है, क्वेरीसलेक्टर * की पठनीयता को प्राथमिकता दी जानी चाहिए। querySelectorAllको फिर से लिखना कठिन है, क्योंकि आपको हर चरण में NodeList या HTMLCollection से तत्वों का चयन करना होगा। उदाहरण के लिए, निम्न कोड काम नहीं करता है:

document.getElementsByClassName("someClass").getElementsByTagName("div")

because you can only use getElements* on single elements, not collections. For example:

`document.querySelector("#someId .someClass div")`

could be written as:

document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]

Note the use of `[0]` to get just the first element of the collection at each step that returns a collection, resulting in one element at the end just like with `querySelector`.
  • चूँकि सभी तत्वों में दोनों क्वेरीसेलर * और गेटइलमेंट * कॉल्स की पहुँच है, आप दोनों कॉल्स का उपयोग करके चेन बना सकते हैं, जो यदि आप कुछ परफॉरमेंस गेन चाहते हैं तो उपयोगी हो सकते हैं, लेकिन किसी ऐसे क्वेरीसेप्टर से नहीं बच सकते, जो गेटेमेंट * कॉल के संदर्भ में नहीं लिखा जा सकता है। ।

  • हालांकि यह आमतौर पर यह बताना आसान है कि क्या चयनकर्ता केवल getElement * कॉल का उपयोग करके लिखा जा सकता है, एक मामला है जो हो सकता है:

    document.querySelectorAll(".class1.class2")

    के रूप में फिर से लिखा जा सकता है

    document.getElementsByClassName("class1 class2")

  • GetElement का उपयोग करके * querySelector * के साथ लाए गए एक स्थिर तत्व पर परिणामस्वरूप एक तत्व होगा, जो DOMS के स्थैतिक उपसमूह के संबंध में लाइव है, जिसे querySelector द्वारा कॉपी किया गया है, लेकिन पूर्ण दस्तावेज़ DOM के संबंध में नहीं है ... यह वह जगह है जहाँ सरल तत्वों की सजीव / स्थैतिक व्याख्या अलग होने लगती है। आपको शायद उन स्थितियों से बचना चाहिए जहां आपको इस बारे में चिंता करनी है, लेकिन यदि आप ऐसा करते हैं, तो याद रखें कि क्वेरीसेलेक्टर * उन प्रतिलिपि तत्वों को कॉल करता है जो उन्हें उनके संदर्भ में लौटने से पहले मिलते हैं, लेकिन getElement * कॉल नकल के बिना सीधे संदर्भ प्राप्त करते हैं।

  • न तो एपीआई निर्दिष्ट करता है कि कौन सा तत्व पहले चुना जाना चाहिए अगर कई मैच हों।

  • क्योंकि querySelector * DOM के माध्यम से iterates करता है जब तक कि उसे एक मैच नहीं मिलता है (मुख्य अंतर # 2 देखें), इसका मतलब यह भी है कि आप DOM में जिस तत्व की तलाश कर रहे हैं, उस पर भरोसा नहीं कर सकते हैं यह गारंटी देने के लिए कि यह जल्दी मिल गया है - ब्राउज़र DOM के माध्यम से पीछे की ओर, आगे, गहराई पहले, चौड़ाई पहले, या अन्यथा हो सकता है। getElement * अभी भी उनके प्लेसमेंट की परवाह किए बिना समय की एक ही राशि में तत्व पाएंगे।


4
इस विषय पर अब तक का सबसे सटीक जवाब। अधिक उखाड़ना चाहिए।
SeaWarrior404 14

बहुत सटीक आपके ब्लॉग में डाला जाना चाहिए, साशा
aking2

25

मैं इस पृष्ठ पर विशुद्ध रूप से प्रदर्शन के मामले में उपयोग करने की बेहतर विधि का पता लगाने के लिए आया था - यानी जो तेज़ है:

querySelector / querySelectorAll or getElementsByClassName

और मुझे यह मिला: https://jsperf.com/getelementsbyclassname-vs-queryselectorall//18

यह ऊपर दिए गए 2 x उदाहरणों पर एक परीक्षण चलाता है, साथ ही यह jQuery के समकक्ष चयनकर्ता के लिए एक परीक्षण में भी चक करता है। मेरे परीक्षा परिणाम इस प्रकार थे:

getElementsByClassName = 1,138,018 operations / sec - <<< clear winner
querySelectorAll = 39,033 operations / sec
jquery select = 381,648 operations / sec

1
वाह, यह एक बड़ा अंतर है, इसे देखने के लिए धन्यवाद। स्पष्ट रूप querySelectorAllसे पर्दे के पीछे अतिरिक्त काम करने की आवश्यकता है (चयनकर्ता की अभिव्यक्ति को पार्स करने के लिए, छद्म तत्वों के लिए लेखांकन, आदि), जबकि getElementsByClassNameकेवल एक पुनरावर्ती वस्तु ट्रैवर्सल है।
जॉन वीज़

18

querySelector एक पूर्ण सीएसएस हो सकता है (3) आईडी और वर्गों और छद्म वर्गों के साथ इस तरह एक साथ चयन:

'#id.class:pseudo'

// or

'tag #id .class .class.class'

साथ getElementByClassNameतुम सिर्फ एक वर्ग को परिभाषित कर सकते हैं

'class'

साथ getElementByIdआप सिर्फ एक आईडी परिभाषित कर सकते हैं

'id'

1
है :firstएक CSS चयनकर्ता अब,? :first-class, या :first-of-typeहो सकता है, लेकिन मुझे लगा :firstकि एक जावास्क्रिप्ट / jQuery / Sizzle जोड़ था।
डेविड का कहना है कि मोनिका

@DavidThomas हाँ यह है, यह CSS3 का हिस्सा है। : यह इस तरह इस्तेमाल किया जा सकता css-tricks.com/almanac/selectors/f/first-child
algorhythm

2
लेकिन :firstध्यान देने योग्य है, नहीं :first-child
डेविड का कहना है कि मोनिका

3
"लेखकों को सलाह दी जाती है कि चयनकर्ताओं में छद्म तत्वों के उपयोग की अनुमति दी जाए, लेकिन वे दस्तावेज़ में किसी भी तत्व से मेल नहीं खाएंगे, और इस तरह किसी भी तत्व को वापस नहीं किया जाएगा। इसलिए, लेखकों को सलाह दी जाती है कि वे छद्म के उपयोग से बचें। चयनकर्ताओं में ऐसे तत्व जो इस विनिर्देशन में परिभाषित विधियों को पारित किए जाते हैं। " w3.org/TR/selectors-api/#grammar
अमीर

इसके अलावा, IE (निश्चित रूप से) में एक बग है जो इसे छद्म तत्वों का चयन करते समय खाली तत्व सूची के बजाय रूट HTML तत्व को वापस करने का कारण बनता है।
अमीर रेमर

7

querySelectorऔर querySelectorAllएक अपेक्षाकृत नए API हैं, जबकि getElementByIdऔर getElementsByClassNameएक बहुत लंबे समय तक के लिए हमारे साथ किया गया है। इसका मतलब है कि आप जो उपयोग करते हैं वह ज्यादातर उन ब्राउज़रों पर निर्भर करेगा जिन्हें आपको समर्थन करने की आवश्यकता है।

इसके लिए :, इसका एक विशेष अर्थ है इसलिए आपको इसे आईडी / क्लास नाम के भाग के रूप में उपयोग करना होगा।


13
आवश्यक रूप से यह सही नहीं है। उदाहरण के लिए, querySelectorAllIE8 में उपलब्ध है, जबकि getElementsByClassNameऐसा नहीं है।
डेवज

querySelectorAll... मूल रूप से सब कुछ: caniuse.com/#search=querySelectorAll
dsdsdsdsd


5

querySelectorw3c सेलेक्टर एपीआई का है

getElementByw3c DOM API का है

IMO सबसे उल्लेखनीय अंतर यह है कि वापसी प्रकार querySelectorAllएक स्थिर नोड सूची है और इसके लिए getElementsByएक लाइव नोड सूची है। इसलिए डेमो 2 में लूपिंग कभी समाप्त नहीं होती है क्योंकि lisलाइव है और प्रत्येक पुनरावृत्ति के दौरान खुद को अपडेट करता है।

// Demo 1 correct
var ul = document.querySelectorAll('ul')[0],
    lis = ul.querySelectorAll("li");
for(var i = 0; i < lis.length ; i++){
    ul.appendChild(document.createElement("li"));
}

// Demo 2 wrong
var ul = document.getElementsByTagName('ul')[0], 
    lis = ul.getElementsByTagName("li"); 
for(var i = 0; i < lis.length ; i++){
    ul.appendChild(document.createElement("li")); 
}

4

"QuerySelector" और "querySelectorAll" के बीच अंतर

//querySelector returns single element
let listsingle = document.querySelector('li');
console.log(listsingle);


//querySelectorAll returns lit/array of elements
let list = document.querySelectorAll('li');
console.log(list);


//Note : output will be visible in Console
<ul>
<li class="test">ffff</li>
<li class="test">vvvv</li>
<li>dddd</li>
<li class="test">ddff</li>
</ul>


2

इसे देखो

https://codepen.io/bagdaulet/pen/bzdKjL

25% पर क्वेरीसेलेक्टर की तुलना में getElementById सबसे तेज़

jquery सबसे धीमी है

var q = time_my_script(function() {

    for (i = 0; i < 1000000; i++) {
         var w = document.querySelector('#ll');
    }

});

console.log('querySelector: '+q+'ms');

-3

QuerySelector और getlementbyID (Claassname, Tagname etc) के बीच मुख्य अंतर यह है कि यदि एक से अधिक ऐसे तत्व हैं जो शर्त को पूरा करते हैं तोSelector केवल एक आउटपुट लौटाएगा जबकि getElementBy * सभी तत्वों को वापस कर देगा।

इसे और अधिक स्पष्ट करने के लिए एक उदाहरण पर विचार करें।

 <nav id="primary" class="menu">
                            <a class="link" href="#">For Business</a>
                            <a class="link" href="#">Become an Instructor</a>
                            <a class="link" href="#">Mobile Applications</a>
                            <a class="link" href="#">Support</a>
                            <a class="link" href="#">Help</a>
   </nav> 

नीचे कोड अंतर की व्याख्या करेगा

**QUERY SELECTOR**
document.querySelector('.link'); // Output : For Business (element)

document.querySelectorAll('.link'); //Out All the element with class link

**GET ELEMENT**
document.getElementsByClassName('link') // Output : will return all the element with a class "link" but whereas in query selector it will return only one element which encounters first.

यदि हम एकल तत्व को क्वैश्चलर के लिए जाना चाहते हैं या अगर हम चाहते हैं कि मल्टीपल तत्व गेटएमेंट के लिए जाए


1
getElementById सिर्फ एक तत्व देता है, यह दोनों के बीच कोई अंतर नहीं है।
टिमोफेई 'साशा' कोंद्रशोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.