Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

javascript - onmouseenter flickering tooltip

I want to display a tooltip when hovering over a svg rect but the tooltip keeps on flickering, switching between display: none and display: flex erratically and unpredictably.

When I used the same code but hovered over a div the result was very smooth, so it seems to be related to the rect element.

I get different behaviours in the snippet below than I do when I open the HTML in Chrome.
In the snippet it seems to work if i enter the rect from left to right or top to bottom, but not the other way around.
In Chrome it just keeps flickering which ever direction I enter.

Why is it behaving this way and what can I do about it?

const tooltips = document.querySelectorAll('.tooltip');
const bars = document.querySelectorAll('rect');

document.addEventListener('mousemove', fn);

function fn(e) {
  tooltips[0].style.left = e.pageX + 'px';
  tooltips[0].style.top = e.pageY + 'px';
}

bars[0].onmouseenter = () => {
  tooltips[0].style.display = 'flex';
}
bars[0].onmouseleave = () => {
  tooltips[0].style.display = 'none';
}
.tooltip {
  display: none;
  position: absolute;
  background-color: grey;
}
<div class="tooltip">
  <p>Rect 1</p>
</div>

<svg width="500" height="500">
    <rect width="200" height="30" x="0" y="0" style="fill:rgb(0,0,255)" />
</svg>
question from:https://stackoverflow.com/questions/66054122/onmouseenter-flickering-tooltip

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Because when the tooltip is opened, it will come over the mouse. And mouseleave for rect is triggered, and tooltip closes and mouseenter is triggered again. So it goes into an infinite loop. We can use pointer-events: none to avoid mouse events on tooltip.

const tooltips = document.querySelectorAll('.tooltip');
const bars = document.querySelectorAll('rect');

document.addEventListener('mousemove', fn);

function fn(e) {
  tooltips[0].style.left = e.pageX + 'px';
  tooltips[0].style.top = e.pageY + 'px';
}

bars[0].onmouseenter = () => {
  tooltips[0].style.display = 'flex';
}
bars[0].onmouseleave = () => {
  tooltips[0].style.display = 'none';
}
.tooltip {
  display: none;
  position: absolute;
  background-color: grey;
  pointer-events: none;
}
<div class="tooltip">
  <p>Rect 1</p>
</div>

<svg width="500" height="500">
    <rect width="200" height="30" x="0" y="0" style="fill:rgb(0,0,255)" />
</svg>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...