2013-08-22 52 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工具中内存使用情况的更多提示。