d3选择器为直系孩子

Sig*_*ied 27 d3.js

我显然可以这样做:

d3.selectAll('div#some-div>ul')
Run Code Online (Sandbox Code Playgroud)

但是如果我使用DOM节点或现有的D3选择怎么办:

d3.select(this).selectAll('ul')
Run Code Online (Sandbox Code Playgroud)

将获得所有后代的UL.因此,如果

var div = d3.select('div') 
Run Code Online (Sandbox Code Playgroud)

给我这个节点:

<div>
  <ul>
    <li>foo
      <ul><li>bar</li></ul>
    </li>
  <ul>
</div>
Run Code Online (Sandbox Code Playgroud)

然后

var uls = div.selectAll('ul') 
Run Code Online (Sandbox Code Playgroud)

会得到两个UL.我想我可以区分出一个顶级的:

uls.filter(function() { return this.parentNode === div.node() }
Run Code Online (Sandbox Code Playgroud)

所以,我已经回答了我自己的问题.也许对某人有用.或许有人可以推荐一个不那么难看的解决方案.

nrabinowitz的答案下面的答案更好,并返回与上面相同的结果.这是一个比较它们修改小提琴(但不使用console.log,这对我来说在jsfiddle中很奇怪)

nra*_*itz 21

我不希望这个工作,但看起来D3将子选择任何元素作为选择的子元素匹配选择器 - 所以这工作:

d3.select(this).selectAll('div > ul');
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/g3aay/2/

  • 这适用于这个具体的答案示例代码.如果`li`在其中包含'<div>`以及'ul`,它仍然会返回它们.是否有更通用的工作解决方案? (10认同)

Xen*_*hor 18

如果有人仍然感兴趣,d3.select(this.childNodes)帮助我解决我挑选所有直系孩子的问题.或者,您可以使用

selection.select(function(){
  return this.childNodes;
})
Run Code Online (Sandbox Code Playgroud)

  • 我相信这是最佳解决方案 (3认同)

Ala*_*sny 6

selection.selectChildren()d3 Selection v2.0 现在应该使用新的/selection.selectChild()方法内置此功能- 请参阅https://github.com/d3/d3-selection/issues/243


Gle*_*enn 5

@nrabinowitz 的解决方案并非一直有效。

就我而言,我试图做d3.select(this).selectAll(".childNode > *").

所以我试图获取 .childNode 的所有直接子节点。问题是这是一个嵌套堆栈,因此 .childNode 也可能出现在子节点中,这会导致问题。

我发现的最好方法是:

var child = d3.select(this).select(".childNode");
var sel = d3.select(this).selectAll(".childNode > *").filter(function() { 
    return this.parentNode == child.node();
});
Run Code Online (Sandbox Code Playgroud)