D3 tooltip的opacity过渡效果不稳定,时好时坏该如何解决?
问题原因
- 未在开启新过渡前终止上一个未完成的过渡:快速移入移出元素时,mouseout的淡出过渡还在运行,此时触发的mouseover淡入过渡会和旧过渡冲突,导致透明度被异常重置,就是你观察到的数值到0.00001就回落的问题。
- tooltip定位后出现在鼠标指针正下方,会触发目标圆形的mouseout事件:鼠标落在tooltip元素上相当于离开了下方的圆形,直接触发淡出逻辑,只有移出后重新移入才能再次触发效果。
- 样式设置逻辑打断了过渡链式调用:你把
transition()的链式调用断开,后续的样式设置直接作用在div元素上,不属于过渡队列,会打断过渡的正常执行逻辑。
修复后代码
// 提前初始化tooltip固定样式,无需每次hover重复赋值 div.style("position", "absolute") .style("text-align", "center") .style("padding", "5px") .style("background", "white") .style("border", "solid") .style("border-width", "2px") .style("border-radius", "5px") .style("pointer-events", "none") // 核心配置:屏蔽tooltip的鼠标事件响应 .style("opacity", 0); var node = svg .selectAll("circle") .data(nodes) .enter() .append("circle") .attr("r", 10) .style("fill", n => n.job.color) .on("mouseover", function(event,d) { // 中断所有未完成的旧过渡,避免队列冲突 div.interrupt() .transition() .duration(200) .style("opacity", 1); // 仅更新动态内容和位置 div.html("Job title: " + d.job.name) .style("left", (event.pageX) + "px") .style("top", (event.pageY - 28) + "px"); }) .on("mouseout", function(d) { div.interrupt() .transition() .duration(500) .style("opacity", 0); });
关键修改说明
- 新增
pointer-events: none样式:彻底屏蔽tooltip的鼠标事件响应,鼠标放在tooltip上也不会触发下方圆形的mouseout事件,解决效果反复横跳的问题 - 每次执行过渡前调用
interrupt():终止之前未完成的透明度过渡,避免新旧过渡的动画队列冲突,不会再出现透明度达不到1的问题 - 固定样式提前初始化:不用每次mouseover都重复设置相同样式,既避免样式设置打断过渡动画,也能提升运行性能
内容的提问来源于stack exchange,提问作者Placidium
相关产品推荐
相关产品推荐

