querySelector तत्काल बच्चों की खोज करें


96

मेरे पास कुछ jquery जैसा कार्य है:

function(elem) {
    return $('> someselector', elem);
};

सवाल यह है कि मैं ऐसा कैसे कर सकता हूं querySelector() ?

>चयनकर्ता querySelector()को स्पष्ट रूप से निर्दिष्ट करने के लिए समस्या चयनकर्ता की आवश्यकता होती है। क्या कोई वर्कअराउंड है?


मैंने एक उत्तर जोड़ा जो आपके लिए बेहतर काम कर सकता है, मुझे बताएं;)
csuwldcat

जवाबों:


119

हालाँकि यह पूर्ण उत्तर नहीं है, आपको W3C सेलेक्टर एपीआई v.2 पर नजर रखनी चाहिए जो पहले से ही अधिकांश ब्राउज़र में उपलब्ध है, IE (एज को सपोर्ट करता है) को छोड़कर: पूर्ण समर्थन सूची देखें

function(elem) {
  return elem.querySelectorAll(':scope > someselector');
};

12
यह सही जवाब है। हालाँकि, ब्राउज़र समर्थन सीमित है और यदि आप इसका उपयोग करना चाहते हैं तो आपको एक शिम की आवश्यकता होगी। मैंने इस उद्देश्य के लिए scopedQuerySelectorShim का निर्माण किया ।
lazd


6
दरअसल, :scopeअभी भी draft.csswg.org/selectors-4/#the-scope-pseudo पर निर्दिष्ट है । अब तक यह केवल <style scoped>विशेषता है जिसे हटा दिया गया है; यह स्पष्ट नहीं है कि क्या यह भी :scopeहटा दिया जाएगा (क्योंकि <style scoped>एक महत्वपूर्ण उपयोग मामला था :scope)।
जॉन मेलोर

1
क्या आश्चर्य की बात है: केवल एज इस का समर्थन नहीं करता है
:)

31

आप नहीं कर सकते। कोई भी चयनकर्ता नहीं है जो आपके शुरुआती बिंदु का अनुकरण करेगा।

जिस तरह से jQuery यह करता है (एक तरीका है कि qsaऐसा व्यवहार जो उनकी पसंद के अनुसार नहीं है के कारण अधिक है), क्या वे यह देखने के लिए जांच करते हैं कि क्याelem क्या आईडी है, और यदि नहीं, तो वे अस्थायी रूप से एक आईडी जोड़ते हैं, फिर एक पूर्ण चयनकर्ता स्ट्रिंग बनाएं।

मूल रूप से आप क्या करेंगे:

var sel = '> someselector';
var hadId = true;
if( !elem.id ) {
    hadID = false;
    elem.id = 'some_unique_value';
}

sel = '#' + elem.id + sel;

var result = document.querySelectorAll( sel );

if( !hadId ) {
    elem.id = '';
}

यह निश्चित रूप से jQuery कोड नहीं है, लेकिन मुझे जो याद है, यह मूल रूप से वे क्या करते हैं। न केवल इस स्थिति में, बल्कि किसी भी स्थिति में जहां आप एक नेस्टेड तत्व के संदर्भ से चयनकर्ता चला रहे हैं।

Sizzle के लिए स्रोत कोड


1
लेखन के समय सही, लेकिन @ avetisk के जवाब के लिए एक अद्यतन विधि देखें।
lazd

23

पूरा: गुंजाइश पॉलीफ़िल

जैसा कि ऐसेटिस्क ने उल्लेख किया है चयनकर्ता एपीआई 2 :scopeछद्म चयनकर्ता का उपयोग करता है ।
इस काम को सभी ब्राउज़रों में करने के लिए (वह समर्थन querySelector) यहाँ पॉलीफ़िल है

(function(doc, proto) {
  try { // check if browser supports :scope natively
    doc.querySelector(':scope body');
  } catch (err) { // polyfill native methods if it doesn't
    ['querySelector', 'querySelectorAll'].forEach(function(method) {
      var nativ = proto[method];
      proto[method] = function(selectors) {
        if (/(^|,)\s*:scope/.test(selectors)) { // only if selectors contains :scope
          var id = this.id; // remember current element id
          this.id = 'ID_' + Date.now(); // assign new unique id
          selectors = selectors.replace(/((^|,)\s*):scope/g, '$1#' + this.id); // replace :scope with #ID
          var result = doc[method](selectors);
          this.id = id; // restore previous id
          return result;
        } else {
          return nativ.call(this, selectors); // use native code for other selectors
        }
      }
    });
  }
})(window.document, Element.prototype);

प्रयोग

node.querySelector(':scope > someselector');
node.querySelectorAll(':scope > someselector');

ऐतिहासिक कारणों से, मेरा पिछला समाधान

सभी उत्तरों के आधार पर

// Caution! Prototype extending
Node.prototype.find = function(selector) {
    if (/(^\s*|,\s*)>/.test(selector)) {
        if (!this.id) {
            this.id = 'ID_' + new Date().getTime();
            var removeId = true;
        }
        selector = selector.replace(/(^\s*|,\s*)>/g, '$1#' + this.id + ' >');
        var result = document.querySelectorAll(selector);
        if (removeId) {
            this.id = null;
        }
        return result;
    } else {
        return this.querySelectorAll(selector);
    }
};

प्रयोग

elem.find('> a');

Date.now()पुराने ब्राउज़र द्वारा समर्थित नहीं है, और साथ प्रतिस्थापित किया जा सकता हैnew Date().getTime()
क्रिस्टोफ़

4

यदि आप उस तत्व का टैग नाम जानते हैं जिसे आप देख रहे हैं, तो आप इसे चयनकर्ता में उपयोग कर सकते हैं कि आप क्या चाहते हैं।

उदाहरण के लिए यदि आप एक है, तो <select>है कि <option>और <optgroups>, और आप केवल चाहते हैं <option>कि इसके तत्काल बच्चों, अंदर नहीं होते हैं <optgoups>:

<select>
  <option>iPhone</option>
  <optgroup>
    <option>Nokia</option>
    <option>Blackberry</option>
  </optgroup>
</select>

इसलिए, चुनिंदा तत्व के संदर्भ में, आप कर सकते हैं - आश्चर्यजनक रूप से - अपने तत्काल बच्चों को इस तरह प्राप्त करें:

selectElement.querySelectorAll('select > option')

यह Chrome, Safari और Firefox में काम करने लगता है, लेकिन IE में परीक्षण नहीं किया। = /


8
चेतावनी: यह उत्तर वास्तव में गुंजाइश सीमित नहीं है। यदि पैटर्न को गहरे घोंसले के स्तर पर दोहराया जाता है, तो यह अभी भी चुना जाएगा, भले ही वह सीधे बच्चे न हों। <ul id="start"> <li>A</li> <li> <ul> <li>b</li> <li>c</li> </ul> </li> </ul> var result = document.getElementById('start').querySelectorAll('ul>li'); -> सभी 4 ली तत्वों का चयन किया जाएगा!
रिसाल्ड डिक्

1
भगवान न <select>करें एक ही माता-पिता में दो तत्व थे।
टॉम ज़ातो -

4

यदि आप अंततः प्रत्यक्ष बच्चों (और उदाहरण के लिए नहीं > div > span) को ढूंढना चाहते हैं, तो आप Element.matches () की कोशिश कर सकते हैं :

const elems = Array.from(elem.children).filter(e => e.matches('.my-class'))

2

दावा

व्यक्तिगत रूप से मैं इसका जवाब पेट्रिक dw से लूंगा, और +1 उसका उत्तर, मेरा उत्तर वैकल्पिक समाधान प्राप्त करने के लिए है। मुझे नहीं लगता कि यह एक पतन का पात्र है।

यहाँ मेरा प्रयास है:

function q(elem){
    var nodes = elem.querySelectorAll('someSeletor');
    console.log(nodes);
    for(var i = 0; i < nodes.length; i++){
        if(nodes[i].parentNode === elem) return nodes[i];
    }
}

http://jsfiddle.net/Lgaw5/8/ देखें


1
उस के साथ समस्याओं का युगल। @ निराश यह चाहता है कि इसके साथ काम किया जाए querySelector, जिसका अर्थ है कि इसका :eq()उपयोग नहीं किया जा सकता है। यहां तक ​​कि अगर यह हो सकता है, तो भी आपका चयनकर्ता उस तत्व को लौटाएगा जो :eq()पृष्ठ पर उसकी उपस्थिति के लिए है, न :eq()कि उसके माता-पिता के सूचकांक (जो कि आपको मिल रहा है idx) के लिए।
user113716

+1 के बारे में: eq () और querySelector। और मुझे संदर्भ $ (हाथी) .परेंट () जोड़ना चाहिए।
लिआंगलियानग झेंग

दुर्भाग्य से यह भी काम नहीं करेगा। जब चयनकर्ता माता-पिता के संदर्भ से चलता है, तो यह बाएं बच्चे के साथ शुरू होता है और सभी मिलान तत्वों को पता चलता है कि कितना भी गहरा घोंसला हो, जारी रहता है। तो कहते हैं कि elemइंडेक्स 4 में है, लेकिन एक पिछले सिबलिंग है जिसमें एक अलग है tagName, लेकिन इसके अंदर नेस्टेड है जिसमें मिलान के साथ एक तत्व है tagName, नेस्टेड एलिमेंट को आपके द्वारा लक्षित किए जाने से पहले परिणामों में शामिल किया जाएगा, फिर से फेंकना होगा। अनुक्रमणिका। यहाँ एक उदाहरण है
user113716

... वैसे भी, जो आप अंततः कर रहे हैं वह प्रश्न में कोड का एक अधिक जटिल संस्करण है, जो काम करता है। $('> someselector', elem);; ओ)
उपयोगकर्ता 113716

हां, लेकिन आपको उस एकल वेतन वृद्धि के लिए कठिन कोड की आवश्यकता थी। इसके लिए पूर्व ज्ञान की आवश्यकता होगी। यदि मैं एक और समान तत्व जोड़ता हूं, तो यह फिर से टूट गया है। ; o) jsfiddle.net/Lgaw5/3
user113716

1

मेरे लिए यह काम किया:

Node.prototype.search = function(selector)
{
    if (selector.indexOf('@this') != -1)
    {
        if (!this.id)
            this.id = "ID" + new Date().getTime(); 
        while (selector.indexOf('@this') != -1)
            selector = selector.replace('@this', '#' + this.id);
        return document.querySelectorAll(selector);
    } else 
        return this.querySelectorAll(selector);
};

जब आप तत्काल बच्चों की खोज करना चाहते हैं तो आपको> से पहले @this कीवर्क पास करना होगा।


वर्तमान स्वीकार किए जाते हैं उत्तर के रूप में ही लगता है ... Btw, अजीब "@" सिंटेक्स की बात क्या है? रेगेक्सप के साथ ">" के लिए सिर्फ टेस्ट क्यों नहीं?
विच्छेदित

1

निम्नलिखित केवल सरल बच्चों पर किसी भी सीएसएस चयनकर्ता क्वेरी को चलाने के लिए एक सरल, सामान्य तरीका है - यह संयुक्त प्रश्नों के लिए भी है, जैसे "foo[bar], baz.boo":

var count = 0;
function queryChildren(element, selector) {
  var id = element.id,
      guid = element.id = id || 'query_children_' + count++,
      attr = '#' + guid + ' > ',
      selector = attr + (selector + '').replace(',', ',' + attr, 'g');
  var result = element.parentNode.querySelectorAll(selector);
  if (!id) element.removeAttribute('id');
  return result;
}


*** Example Use ***

queryChildren(someElement, '.foo, .bar[xyz="123"]');

1

एक क्वेरी-रिलेटिव लीव है, जो क्वेरी-सिलेक्टर के लिए काफी आसान प्रतिस्थापन है । यह बच्चों के चयनकर्ता '> *'और :scope(inc। IE8) को पॉलीफिल करता है, साथ ही :rootचयनकर्ता को सामान्य बनाता है । इसके अलावा ऐसा कुछ विशेष रिश्तेदार pseudos प्रदान करता है :closest, :parent, :prev, :next, बस मामले में।


0

जाँच करें कि क्या तत्व में id है और यादृच्छिक आईडी जोड़ें और उसके आधार पर खोज करें

function(elem) {
      if(!elem.id)
          elem.id = Math.random().toString(36).substr(2, 10);
      return elem.querySelectorAll(elem.id + ' > someselector');
    };

के रूप में एक ही बात करेंगे

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