querySelectorsearch直接的孩子
我有一些jQuery般的function:
function(elem) { return $('> someselector', elem); };
问题是我怎么可以做同样的querySelector()
?
问题是>
querySelector()
select器要求父显式指定。 有没有解决办法?
虽然这不是一个完整的答案,但您应该留意已经在Google Chrome和Safari 7.x(包括桌面和移动设备)中可用的W3C Selector API v.2 ,但是据我testing,仍然不存在在Firefox和IE中。
function(elem) { return elem.querySelectorAll(':scope > someselector'); };
你不能。 没有select器可以模拟你的出发点。
jQuery的做法(更多的是因为qsa
行为方式不符合自己的喜好)是检查elem
是否有ID,如果不是,他们临时添加一个ID,然后创build一个完整的select器string。
基本上你会这样做:
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代码,但从我记忆中,这基本上是他们所做的。 不仅在这种情况下,而且在任何情况下,你从一个嵌套元素的上下文运行一个select器。
Sizzle的源代码
完成:示波器填充
由于avetisk已经提到了select器API 2使用:scope
伪select器。
为了使所有浏览器(支持querySelector
)的工作在这里是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);
用法
node.querySelector(':scope > someselector'); node.querySelectorAll(':scope > someselector');
由于历史原因,我以前的解决scheme
基于所有的答案
// 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');
如果您知道要查找的元素的标记名称,则可以在select器中使用它以实现所需的function。
例如,如果您有一个<select>
具有<option>
s和<optgroups>
,并且您只需要作为其直接子元素的<option>
s,而不是<optgoups>
:
<select> <option>iPhone</option> <optgroup> <option>Nokia</option> <option>Blackberry</option> </optgroup> </select>
所以,通过引用select元素,你可以 – 出人意料地 – 得到它的直接子元素:
selectElement.querySelectorAll('select > option')
它似乎在Chrome,Safari和Firefox中工作,但没有在IE中testing。 = /
这对我有用:
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); };
当你想要search直接的孩子时,你必须通过@这个关键词。
以下是一个简单的通用方法,用于仅通过直接子对象运行任何CSSselect器查询 – 它也考虑了组合查询,如"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"]');
有一个查询相关库,这是查询select器相当方便的替代品。 它填充的孩子select器'> *'
和:scope
(包括IE8),以及规范化:root
select器。 还提供了一些特殊的相对伪像,如:closest
, :parent
, :prev
, :next
,以防万一。
要求
就个人而言,我会从帕特里克dw的答案,并+1他的答案,我的答案是寻求替代解决scheme。 我认为这不值得赞成。
这是我的尝试:
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]; } }
检查元素是否有id另外添加随机id并根据它进行search
function(elem) { if(!elem.id) elem.id = Math.random().toString(36).substr(2, 10); return elem.querySelectorAll(elem.id + ' > someselector'); };
会做同样的事情
$("> someselector",$(elem))