admin管理员组文章数量:1359429
The normal way of handling onclick in d3 is
selection.append(element)
.on("click", someFunction)
If I do it this way on 1000 svg elements, does it mean I just attached 1000 different listeners. If this is the case, is there event delegation for d3 specifically?
The normal way of handling onclick in d3 is
selection.append(element)
.on("click", someFunction)
If I do it this way on 1000 svg elements, does it mean I just attached 1000 different listeners. If this is the case, is there event delegation for d3 specifically?
Share Improve this question edited Jan 3, 2018 at 15:32 Gerardo Furtado 102k9 gold badges128 silver badges177 bronze badges asked Jan 3, 2018 at 14:44 Loredra LLoredra L 1,5532 gold badges17 silver badges35 bronze badges 03 Answers
Reset to default 8@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/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/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./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.
Here is a d3 svg event delegation implementation: d3-delegation.
You can download the node module with: npm i --save d3-delegation
.
Click me to the demo.
本文标签: javascriptDo I add eventListener to every SVG element if I follow normal D3 wayStack Overflow
版权声明:本文标题:javascript - Do I add eventListener to every SVG element if I follow normal D3 way? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743873780a2553955.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论