Do I add eventListener to every SVG element if I follow normal D3 way?

@AlexW answer is (partially) correct: there is no event delegation in D3, only event binding.

However, I said partially because it'd be better saying that "there is no native method for event delegation in D3", since in fact it's quite ease to implement it: the ugly alternative to do event delegation with D3 consists in using d3.event.target.

For instance, in this very simple demo, we bind this data...

var data = ["foo", "bar", "baz"];

... to the circles inside an <g> element. Then, we bind an event listener to the group, and get the datum of each circle on click:

g.on("click", function() {
  console.log(d3.select(d3.event.target).datum())
})

Here is it:

var svg = d3.select("svg");
var g = svg.append("g");
var data = ["foo", "bar", "baz"];
var circles = g.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", 40)
  .attr("cx", function(_, i) {
    return 50 + 100 * i
  })
  .attr("r", 20)
  .attr("fill", "teal");

g.on("click", function() {
  console.log(d3.select(d3.event.target).datum())
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

The nice thing about this approach is that, just as a jQuery event delegation, it works with elements created after the listener was defined. In the following demo, the red circle:

var svg = d3.select("svg");
var g = svg.append("g");
var data = ["foo", "bar", "baz"];
var circles = g.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", 40)
  .attr("cx", function(_, i) {
    return 50 + 75 * i
  })
  .attr("r", 20)
  .attr("fill", "teal");

g.on("click", function() {
  console.log(d3.select(d3.event.target).datum())
});

g.append("circle")
  .attr("cy", 40)
  .attr("cx", 275)
  .attr("r", 20)
  .attr("fill", "firebrick")
  .datum("foobar")
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

So, despite D3 not having a native, explicit method for event delegation, the solution is quite simple and straightforward.


Yes this would add 1000 event listeners:

Adds or removes a listener to each selected element for the specified event typenames.

https://github.com/d3/d3-selection/blob/master/README.md#selection_on

If you have 1000+ elements, you may not want to use SVG, as the DOM gets easily bogged down with that many elements. It may be more efficient to use a canvas, etc.

D3 doesn't do event delegation it only does event binding. So you may want to implement the delegation using jQuery or vanilla JS, if you're still considering using SVG.