2013-08-22 10 views
7

Ich habe Code, der einen Mouseover-Event-Handler zu Svg-Kreisen hinzufügt, um Tooltips anzuzeigen. Sollte ich diese Handler entfernen/lösen, wenn ich die Kreiselemente entferne? Ich weiß nicht, ob diese Handler an das Svg-Objekt angehängt sind und ich befürchte, dass es zu Schatten-DOM oder Speicherlecks kommen kann. Siehe Code unten:d3.js sollte ich Event Listener beim Beenden/Entfernen trennen?

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

Das Entfernen der Elemente sollte auch die Ereignislistener entfernen. –

+0

@LarsKotthoff Meinst du, dass Entwickler sollte Ereignis entfernen, wenn Element (manuell) entfernen oder dass D3 sollte es für uns tun? – Necriis

+0

Sie können kein Ereignis an nichts anhängen lassen. Es wird der Event-Handler automatisch entfernt, wenn das Element entfernt wird. –

Antwort

15

Ich glaube, Sie haben Ihre Antwort schon, aber ich war daran interessiert, wie Sie zeigen, dass dies wahr ist, zumindest in neuestem Chrome.

Dies ist die section of the D3 code, die DOM-Knoten entfernt:

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

So wie Sie es je nach Browser Bereinigung aller zugehörigen Zuhörer zu tun sehen.

habe ich einen einfachen Stresstest Hinzufügen/Entfernen von vielen Kreisknoten mit 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') });  

Live-Version hier: http://bl.ocks.org/explunit/6413685

  1. öffnen Sie die oben mit dem neuesten Chrome
  2. öffnen Entwicklerwerkzeuge
  3. Klicken Sie auf die Registerkarte Timeline
  4. Klicken Sie auf Re Schnur-Taste am unteren Rande
  5. es für ein paar Minuten laufen lassen, dann erneut auf die Schaltfläche klicken Sie in der oberen Timeline-Ansicht Aufnahme
  6. Ziehen Sie die Wahl zu stoppen mehrere der Garbage Collection Sägezahnmuster zu decken

Sie werden feststellen, dass die Anzahl der Garbage-Collection-Zählungen im DOM-Knoten den Zählwerten der Ereignis-Listener-Garbage Collection entspricht. In der Tat kann man sie nicht wirklich in dem Screenshot unten auseinanderzuhalten, da die Linien überlagern:

Chrome Screenshot

Beachten Sie, dass für den Internet Explorer, things are a little more complicated.

Weitere Tipps zum Verfolgen der Speichernutzung in Chrome-Tools finden Sie unter this article.