d3.js v6+版本中实现标记点击元素的最佳解决方案
D3.js v6+ 点击元素记录对应datum的实现方案
核心差异说明
D3.js从v6版本开始调整了事件监听器的回调参数顺序,这是原有写法失效的核心原因:
- v3版本:回调参数前两位为
(datum, index),事件对象需要通过d3.event全局获取 - v6+版本:回调参数第一位为原生事件对象
event,第二位才是元素绑定的datum,很多迁移用户会误把第一个参数当datum使用导致取值错误。
优化后可运行实现
以下是适配v6+版本的代码,同时修正了原示例的笔误、加入D3通用更新模式避免重复创建元素:
const data = [ {x: 10, y: 20}, {x: 30, y: 10}, {x: 20, y: 55}, ]; const svg = d3.select("#div1") .append("svg") .attr("width", 100) .attr("height", 100); let clickedCircle = null; function update() { // 绑定数据分离更新、新增、移除逻辑 const circles = svg.selectAll("circle") .data(data); // 处理新增元素 circles.enter() .append("circle") .attr("r", 10) // v6+ 事件回调第一位是event,第二位是绑定的datum .on("click", (event, d) => { clickedCircle = d; update(); }) // 合并新增和已有元素统一更新属性 .merge(circles) .attr("cx", d => d.x) .attr("cy", d => d.y) .style("fill", d => d === clickedCircle ? "red" : "black"); // 处理需要移除的元素(数据减少时自动清理) circles.exit().remove(); } // 初始化渲染 update();
扩展说明
如果后续需要获取当前点击的DOM元素而非仅绑定的数据,可以通过event.currentTarget属性直接获取,不需要依赖传统的this指向,适配现代JS箭头函数的编码习惯。
内容的提问来源于stack exchange,提问作者AstronAUT
相关产品推荐
相关产品推荐

