2016-03-05 183 views
4

selection.node()返回only the first節點。我們可以從選擇中獲得所有節點的數組嗎?從d3選擇獲取所有dom節點

編輯添加了一些代碼來幫助我們。

  • each()的嘗試產生希望 輸出只有一個,雖然非常詳細。
  • 調用sel[0]也返回一個帶有DOM節點的數組,但它很不方便(取決於庫的內部結構),並且包含一個不需要的「parentNode」字段。

// creating a selection to experiment with 
 
var data= [1,2,3,4] 
 
var sel = d3.select("li") 
 
\t .data(data) 
 
\t .enter().append("li").html(identity); 
 
function identity(d){return d} 
 
console.log(sel); // array[1] with array[4] with the <li>'s 
 

 
// using .node() 
 
var res1 = sel.node(); 
 
console.log(res1); // first <li> only 
 

 
// using .each() to accumulate nodes in an array 
 
var res2 = []; 
 
function appendToRes2(){ 
 
\t res2.push(this); 
 
} 
 
sel.each(appendToRes2); 
 
console.log(res2); // array[4] with the <li>'s (what I want) 
 

 
// calling sel[0] 
 
var res3 = sel[0]; 
 
console.log(res3); // array[4] with the <li>'s plus a "parentNode" 
 

 
// @thisOneGuy's suggestion 
 
var res4 = d3.selectAll(sel); 
 
console.log(res4); // array[1] with array[1] with array[4] with the <li>'s
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

EDIT 2爲什麼我要這麼做?
在DOM節點上調用array methods,如reducemap。 D3提供了filter,但要使用其他人我首先需要從選擇中提取節點數組。

+0

怎麼樣selection.each(功能)。它在你提供的鏈接 – Mike

+0

是的,我可以調用'each',從'this'獲取dom節點並將它們累加到一個外部變量中。看起來'selection [0]'也是一樣的。我想知道是否沒有更清潔/更簡單的方法。 – Vituel

+0

d3.selectAll(選擇)?添加一些代碼,以便我可以更好地理解您的問題 – thatOneGuy

回答

6

我最初寫這個作爲一個評論,但決定把它變成一個答案...

它看起來像D3 V4將include the functionality you want。如果你不想等待,你可以偷implementation now,並將其添加到選擇的原型:

d3.selection.prototype.nodes = function(){ 
    var nodes = new Array(this.size()), i = -1; 
    this.each(function() { nodes[++i] = this; }); 
    return nodes; 
} 

用例:

d3.selection.prototype.nodes = function(){ 
 
    var nodes = new Array(this.size()), i = -1; 
 
    this.each(function() { nodes[++i] = this; }); 
 
    return nodes; 
 
} 
 

 

 
var data= [1,2,3,4] 
 
var sel = d3.select("li") 
 
\t .data(data) 
 
\t .enter().append("li").html(identity); 
 
function identity(d){return d} 
 

 
console.log(sel.nodes());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

由於來自@mbostock,這是一個很好的選擇,是最好的實現。

+0

但是這種方法也使用'.each()',對吧?通過構建一個新的數組,它基本上與OP的appendToRes2()相同。因爲它使用了一個預定義大小的數組而不是推送到一個數組,所以它可能會稍微高效一些。 – altocumulus

+0

@altcumulus,是的,它是一樣的。我把它寫成了答案,因爲這是'd3'的作者在即將發佈的v4版本中完成的方式。那麼在「正確的方式去做」之後,你就無法獲得更多的權威。 – Mark