D3.js集成更新函数后鼠标悬停事件失效问题排查求助
问题排查:D3.js Update函数中Mouseover事件无法触发
核心问题原因
你把事件监听器绑定在了**过渡(transition)**对象上,而非直接绑定到矩形元素上。D3的transition()返回的是过渡实例,不支持事件监听,所以你的mouseover/mouseout事件根本没注册到DOM元素上,自然无法触发。
另外注意:D3 v6+版本的事件处理函数参数顺序是(event, d),你的onMouseOut函数参数顺序写反了(当前是(d, i)),这会导致后续逻辑出错。
修复方案
- 将事件监听器移到
merge(u)之后、.transition()之前,确保绑定到实际的DOM元素 - 修正
onMouseOut的参数顺序
修改后的完整代码
function onMouseOver(event, d){ d3.select(this) .attr('class', 'tooltip') .transition() .duration(200); const g = d3.select(this.parentNode); g.append('text') .attr('class', 'val') .attr('x', () => x(d.event_name)) .attr('y', () => y(d.total_event/2)) .text(() => [d.total_event]); }; // 修正参数顺序:第一个参数是event,第二个是数据d function onMouseOut(event, d){ d3.select(this).attr('class', 'bar'); d3.select(this) .transition() .duration(400); d3.selectAll('.val') .remove() } function update(dataBar) { x.domain(dataBar.map(d => d.event_name)) xAxis.call(d3.axisBottom(x)) .selectAll("text") .attr("class", "axis-label") .attr("transform", "rotate(-45)") .style("text-anchor", "end"); y.domain([0, d3.max(dataBar, d => d.total_event)]) .nice() yAxis.transition().duration(1000).call(d3.axisLeft(y).ticks(10)); const u = svgBar.selectAll(".bar") .data(dataBar) u.enter().append("rect") .attr("class", "bar") .merge(u) // 先绑定事件监听器到元素,再执行过渡动画 .on("mouseover", onMouseOver) .on("mouseout", onMouseOut) .transition() .duration(1000) .attr("x", d => x(d.event_name)) .attr("y", d => y(d.total_event)) .attr("width", x.bandwidth()) .attr("height", d => heightBar - y(d.total_event)); u.exit().remove() }
内容的提问来源于stack exchange,提问作者user21392216
相关产品推荐
相关产品推荐

