我可以这样做:

<div id="myDiv">
   <div class="foo"></div>
</div>
myDiv = getElementById("myDiv");
myDiv.querySelectorAll("#myDiv > .foo");

也就是说,我可以成功地检索myDiv元素的所有具有类.foo的直接子元素。

问题是,它困扰我,我必须包括在选择器中的#myDiv,因为我是在myDiv元素上运行查询(所以它显然是多余的)。

我应该能够离开#myDiv关闭,但选择器是不合法的语法,因为它以>开始。

有人知道如何编写一个选择器,它只获取选择器所运行的元素的直接子元素吗?


当前回答

我想补充的是,您可以通过为当前节点分配临时属性来扩展:scope的兼容性。

let node = [...];
let result;

node.setAttribute("foo", "");
result = window.document.querySelectorAll("[foo] > .bar");
// And, of course, you can also use other combinators.
result = window.document.querySelectorAll("[foo] + .bar");
result = window.document.querySelectorAll("[foo] ~ .bar");
node.removeAttribute("foo");

其他回答

我只是没有尝试就这么做了。这样能行吗?

myDiv = getElementById("myDiv");
myDiv.querySelectorAll(this.id + " > .foo");

试一试,也许有用,也许没用。抱歉,但我现在不在电脑上尝试它(从我的iPhone回复)。

你可以像这样扩展Element来包含一个getDirectDesc()方法:

Element.prototype.getDirectDesc = function() { const descendants = Array.from(this.querySelectorAll('*')); const directDescendants = descendants.filter(ele => ele.parentElement === this) return directDescendants } const parent = document.querySelector('.parent') const directDescendants = parent.getDirectDesc(); document.querySelector('h1').innerHTML = `Found ${directDescendants.length} direct descendants` <ol class="parent"> <li class="b">child 01</li> <li class="b">child 02</li> <li class="b">child 03 <ol> <li class="c">Not directDescendants 01</li> <li class="c">Not directDescendants 02</li> </ol> </li> <li class="b">child 04</li> <li class="b">child 05</li> </ol> <h1></h1>

我会和你一起去的

var myFoo = document.querySelectorAll("#myDiv > .foo");
var myDiv = myFoo.parentNode;

我们可以很容易地使用childNodes获取元素的所有直接子元素,也可以使用querySelectorAll选择特定类的祖先元素,因此不难想象,我们可以创建一个新函数来获取两者并比较两者。

HTMLElement.prototype.queryDirectChildren = function(selector){
  var direct = [].slice.call(this.directNodes || []); // Cast to Array
  var queried = [].slice.call(this.querySelectorAll(selector) || []); // Cast to Array
  var both = [];
  // I choose to loop through the direct children because it is guaranteed to be smaller
  for(var i=0; i<direct.length; i++){
    if(queried.indexOf(direct[i])){
      both.push(direct[i]);
    }
  }
  return both;
}

注意:这将返回一个节点数组,而不是一个节点列表。

使用

 document.getElementById("myDiv").queryDirectChildren(".foo");

下面的解决方案与到目前为止提出的解决方案不同,对我来说是可行的。

基本原理是首先选择所有匹配的子节点,然后过滤掉不是直接子节点的子节点。如果子元素没有具有相同选择器的匹配父元素,则子元素是直接子元素。

function queryDirectChildren(parent, selector) {
    const nodes = parent.querySelectorAll(selector);
    const filteredNodes = [].slice.call(nodes).filter(n => 
        n.parentNode.closest(selector) === parent.closest(selector)
    );
    return filteredNodes;
}

HTH!