2013-08-22 80 views
7

我有一些代碼添加一個mouseover事件處理程序到svg圈顯示工具提示。我應該刪除/取消綁定這些處理程序時,我刪除了圓形元素?我不知道這些處理程序是否附加到svg對象,我擔心它可能會導致陰影或內存泄漏。請參見下面的代碼:d3.js我應該退出/移除事件監聽器嗎?

circles.enter().append("svg:circle") 
    .on("mouseenter", function(d) { 
     // show tooltip 
    }); 
circles.exit() 
    .on("mouseenter", null) // necessary? 
    .remove(); 
+4

刪除元素也應刪除事件偵聽器。 –

+0

@LarsKotthoff你的意思是開發人員應該在刪除元素時手動刪除事件,或者D3應該爲我們做這件事嗎? – Necriis

+0

您不能將任何事件附加到任何東西上。它將在移除元素時自動移除事件處理程序。 –

回答

15

我覺得你有你的答案了,不過我很感興趣,你如何證明這是真的,至少在最新的Chrome。

這是section of the D3 code去除DOM節點:

d3_selectionPrototype.remove = function() { 
    return this.each(function() { 
     var parent = this.parentNode; 
     if (parent) parent.removeChild(this); 
    }); 
    }; 

因此,大家可以看到它的視瀏覽器做任何相關的聽衆清理。

我創建添加/刪除很多圈節點與D3的一個簡單的壓力測試:

var circles = svg.selectAll("circle") 
    .data(data, function(d) { return d.id; }); 

    circles.exit().remove(); 

    circles.enter().append("circle") 
    .attr("id", function(d) { return d.id; }) 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }) 
    .attr({ r: 5, fill: 'blue' }) 
    .on("mouseenter", function(d) { console.log('mouse enter') });  

住在這裏的版本:http://bl.ocks.org/explunit/6413685

  1. 打開上面最新的Chrome
  2. 打開開發人員工具
  3. 單擊時間軸選項卡
  4. 單擊Re在底部
  5. 線按鈕,讓它運行幾分鐘,然後再次單擊該按鈕停止錄製
  6. 將選擇在頂時間軸視圖覆蓋幾個垃圾收集的鋸齒圖案

您會注意到DOM節點垃圾收集計數與事件偵聽器垃圾收集計數相對應。其實,你真的不能告訴他們除了在下面的截圖,因爲線是重疊的:

Chrome Screenshot

注意的Internet Explorer,things are a little more complicated

另請參閱this article瞭解有關跟蹤Chrome工具中內存使用情況的更多提示。