2012-04-17 15 views
19

पर `querySelectorAll` का उपयोग करके बाल चयनकर्ता मान लें कि आपको नेस्टेड बाल सूचियों के साथ एक सूची मिली है।एक DOM संग्रह

<ul> 
    <li></li> 
    <li> 
     <ul> 
      <li></li> 
      <li></li> 
     </ul> 
    </li> 
    <li></li> 
</ul> 

और document.querySelectorAll() का उपयोग चयन करने के लिए:

var ul = document.querySelectorAll("ul"); 

मैं कैसे ul संग्रह का उपयोग प्रत्यक्ष बच्चे तत्वों प्राप्त करने के लिए कर सकते हैं?

ul.querySelectorAll("> li"); 
// Gives 'Error: An invalid or illegal string was specified' 

के अनुमान ul किसी भी तरह से कैश की गई (अन्यथा मैं ul > li सीधे किया जा सकता है) कर रहा है।

jQuery में यह काम करता है:

$("ul").find("> li"); 

लेकिन यह देशी querySelectorAll में नहीं है। कोई समाधान?

+2

चयनकर्ता वास्तव में मतलब नहीं है यही कारण है कि:

ul.querySelectorAll(":scope > li"); 

मेरा उत्तर यहाँ एक विवरण और एक मजबूत, क्रॉस-ब्राउज़र समाधान के लिए देखें। JQuery के साथ आप '.findren ("> li") के बजाय '.children (" li ")' का उपयोग करेंगे। मैं आश्चर्यचकित हूं कि वास्तव में काम करता है। –

+0

@ MДΓΓБДLL '.find ('> li ul span') 'उपयोगी है, लेकिन ओपी के उदाहरण में इसकी तरह नहीं है। – alex

+0

@ MДΓΓБДLL उदाहरण थोड़ा सा है, लेकिन यह निश्चित रूप से वास्तविक दुनिया का उपयोग केस है :) – Husky

उत्तर

12

क्योंकि ul लौटाया गया एक नोडलिस्ट है, यह एक jQuery संग्रह की तरह इसकी सामग्री पर स्पष्ट रूप से लूप नहीं करता है। आपको ul[0].querySelectorAll() का उपयोग करने की आवश्यकता होगी या ulquerySelector() के साथ अभी भी बेहतर चुनें।

इसके अलावा, querySelectorAll()> नहीं लेगा और इसके वर्तमान संदर्भ से कार्य नहीं करेगा। हालांकि, अगर आप यह lazd's answer का उपयोग कर काम करने के लिए प्राप्त कर सकते हैं (हालांकि ब्राउज़र संगतता जांचें), या इन समाधानों (कोई ब्राउज़र मुद्दे हैं चाहिए) के किसी भी ...

[].filter.call(ul.querySelectorAll("li"), function(element){ 
    return element.parentNode == ul; 
}); 

jsFiddle

यह आपके li तत्वों का चयन करेगा जो आपके ul के वंशज हैं, और फिर उन लोगों को हटा दें जो प्रत्यक्ष वंशज नहीं हैं।

वैकल्पिक रूप से, आप सभी childNodes मिल सकता है और उसके बाद उन्हें फ़िल्टर ...

[].filter.call(ul.childNodes, function(node) { 
    return node.nodeType == 1 && node.tagName.toLowerCase() == 'li'; 
}); 

jsFiddle

+0

Yup, यह एक व्यावहारिक समाधान की तरह लगता है।बहुत बुरा यह कोड की तीन पंक्तियां लेता है जो एक ही चरित्र में किया जा सकता है :) ध्यान दें कि 'फ़िल्टर') काम नहीं करेगा क्योंकि 'उल' एक नोडलिस्ट है, इसलिए आपको 'Array.prototype.slice' करने की आवश्यकता है पहले। – Husky

+0

@ हूस्की यह जिस तरह से मैंने लिखा है, वैसे ही काम करेगा। – alex

+0

@ हूस्की आप इसे हमेशा एक तत्व के रूप में 'Element.prototype' में जोड़ सकते हैं :) –

0

आपको NodeList पर document.querySelectorAll() पर लौटने की आवश्यकता है और फिर उस सूची में प्रत्येक तत्व के लिए element.querySelectorAll() पर कॉल करें।

36

वर्तमान तत्व को "रूट" करने वाले चयनकर्ता को लिखने का सही तरीका :scope का उपयोग करना है। https://stackoverflow.com/a/21126966/1170723

+2

यह देखने के लिए अच्छा है! :) – alex

+5

ध्यान रखें [ब्राउज़र संगतता] (https://developer.mozilla.org/en-US/docs/Web/CSS/%3ascope#Browser_compatibility): क्रोम: हाँ, एफएफ: 32, आईई: नहीं, ओपेरा: नहीं, सफारी: 7 –

+0

@Web_Designer के अलावा, इस दिन तक यह अभी भी * माइक्रोसॉफ्ट एज में समर्थित नहीं है। QuerySelectorAll में 'स्कोप' का उपयोग करने का प्रयास एक वाक्यविन्यास त्रुटि देता है। "आपको jQuery की आवश्यकता नहीं है" शिविर के लिए बहुत कुछ। – TKoL