QuerySelector Instant Children Search

I have a jquery-like function:

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

The question is, how can I do the same with querySelector() ?

The > selector task in querySelector() requires the parent pointer to be explicitly pointed. Is there any workaround?

+51
javascript css-selectors selectors-api
Jun 26 2018-11-11T00:
source share
9 answers

Finish: polyfill area

Since avetisk has the one mentioned , the API 2 selectors use the :scope pseudo-selector.
To make this work in all browsers (supporting querySelector ), here is the polyfill

 (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); 

Using

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



For historical reasons, my previous decision

Based on all answers

 // 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); } }; 

Using

 elem.find('> a'); 
+13
Aug 01 '13 at 9:12
source share

Although this is not a complete answer, you should follow the W3C Selector API v.2 , which is already available in Google Chrome and Safari 7.x (both on the desktop and on mobile devices), but as far as I tested, so far does not exist in Firefox and IE.

 function(elem) { return elem.querySelectorAll(':scope > someselector'); }; 
+66
Sep 04 '13 at 7:23
source share

You can not. There is no selector that will mimic your starting point.

The jQuery way of doing this (more because of the way qsa behaves differently) is that they check if elem identifier, and if not, they temporarily add an identifier, then create a full selector string.

Basically you would do:

 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 = ''; } 

This, of course, is not jQuery code, but from what I remember, it is basically what they do. Not only in this situation, but also in any situation when you use a selector from the context of a nested element.

Source Code for Sizzle

+27
Jun 26 2018-11-11T00:
source share

If you know the tag name of the element you are viewing, you can use it in the selector to achieve what you want.

For example, if you have <select> with <option> and <optgroups> , and you want <option> be its immediate children, and not the ones inside <optgoups> :

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

So, having a reference to the select element, you can - surprisingly - get your immediate children as follows:

 selectElement.querySelectorAll('select > option') 

It works in Chrome, Safari, and Firefox, but has not been tested in IE. = /

+5
Oct 18 '15 at 17:17
source share

This worked for me:

 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); }; 

you will need to pass @this keywork before> when you want to find instant children.

+1
Jul 16 2018-12-12T00:
source share

The following is a simplified general method for launching any CSS selector query only for direct children - it also takes into account combined queries, such as "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
Jul 29
source share

Theres a query-relative lib, which is pretty handy for the query selector. It polishes the child selector '> *' and :scope (including IE8), and also normalizes the :root selector. It also provides some special relative pseudo-pods, such as :closest :parent :prev :next , just in case.

+1
Dec 09 '14 at 23:10
source share

SUIT

Personally, I would take the answer from patrick dw, and +1 his answer, my answer is to look for an alternative solution. I don't think he deserves a demotion.

Here is my attempt:

 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]; } } 

see http://jsfiddle.net/Lgaw5/8/

0
Jun 26 '11 at 2:27
source share

check if id element still has random identifier added and search on it

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

will do the same as

 $("> someselector",$(elem)) 
0
Feb 26 '15 at
source share



All Articles