dis*_*ted 82 javascript css-selectors selectors-api
我有一些类似jquery的功能:
function(elem) {
return $('> someselector', elem);
};
Run Code Online (Sandbox Code Playgroud)
问题是我怎么能这样做querySelector()
?
问题是>
选择器querySelector()
要求明确指定父级.有没有解决方法?
ave*_*isk 106
虽然这不是一个完整的答案,但你应该关注W3C Selector API v.2,它已经在谷歌Chrome和Safari 7.x(桌面和移动设备)中提供,但据我测试,仍然没有在Firefox和IE中.
function(elem) {
return elem.querySelectorAll(':scope > someselector');
};
Run Code Online (Sandbox Code Playgroud)
use*_*716 31
你不能.没有选择器可以模拟你的起点.
jQuery的做法(更多是因为一种qsa
行为不符合他们的喜好)是他们检查是否elem
有ID,如果没有,他们会临时添加ID,然后创建一个完整的选择器字符串.
基本上你会这样做:
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 = '';
}
Run Code Online (Sandbox Code Playgroud)
这当然不是jQuery代码,但从我记忆中,它基本上就是他们所做的.不只是在这种情况下,而是在您从嵌套元素的上下文中运行选择器的任何情况下.
dis*_*ted 19
正如avetisk已经提到的选择器API 2使用:scope
伪选择.
要在所有浏览器(支持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);
Run Code Online (Sandbox Code Playgroud)
node.querySelector(':scope > someselector');
node.querySelectorAll(':scope > someselector');
Run Code Online (Sandbox Code Playgroud)
由于历史原因,我以前的解决方案
基于所有答案
// 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);
}
};
Run Code Online (Sandbox Code Playgroud)
用法
elem.find('> a');
Run Code Online (Sandbox Code Playgroud)
如果你想最终找到直接的孩子(而不是 eg > div > span
),你可以尝试Element.matches():
const elem = document.body
const elems = [...elem.children].filter(e => e.matches('b'))
console.log(elems)
Run Code Online (Sandbox Code Playgroud)
<a>1</a>
<b>2</b>
<b>3</b>
<b>4</b>
<s>5</s>
Run Code Online (Sandbox Code Playgroud)
宣称
我个人会从 patrick 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];
}
}
Run Code Online (Sandbox Code Playgroud)
如果您知道要查看的元素的标签名称,那么您可以在选择器中使用它来实现您想要的。
例如,如果你有一个<select>
有<option>
S和<optgroups>
,你只希望<option>
这是其直接的孩子,而不是里面的那些小号<optgoups>
:
<select>
<option>iPhone</option>
<optgroup>
<option>Nokia</option>
<option>Blackberry</option>
</optgroup>
</select>
Run Code Online (Sandbox Code Playgroud)
所以,有了对 select 元素的引用,你可以——令人惊讶地——像这样获得它的直接子元素:
selectElement.querySelectorAll('select > option')
Run Code Online (Sandbox Code Playgroud)
它似乎适用于 Chrome、Safari 和 Firefox,但未在 IE 中进行测试。=/
归档时间: |
|
查看次数: |
47234 次 |
最近记录: |