"Smart" 工具提示
重要程度: 5
编写一个函数,仅在访问者将鼠标移动到它上面而非通过它时,才会显示元素上的工具提示。
换句话说,如果访问者把鼠标移动到元素上,然后停下 —— 显示工具提示。如果访问者将鼠标快速移过元素,那就不需要显示,谁想要多余的内容呢?
从技术上说,我们可以测量鼠标在元素上的经过速度,如果速度很慢,那么我们认为它在元素上并显示工具提示,如果速度太快 —— 那么我们就忽略它。
为它创建一个通用对象 new HoverIntent(options)
,加上 options
:
elem
—— 要跟踪的元素。over
—— 如果鼠标缓慢地移动元素,调用该函数。out
—— 当鼠标离开元素时,调用函数(如果over
被调用过了)。
在工具提示中使用此类对象的示例:
// 工具提示样本
let tooltip = document.createElement('div');
tooltip.className = "tooltip";
tooltip.innerHTML = "Tooltip";
// 对象将跟踪鼠标,并调用 over/out
new HoverIntent({
elem,
over() {
tooltip.style.left = elem.getBoundingClientRect().left + 'px';
tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px';
document.body.append(tooltip);
},
out() {
tooltip.remove();
}
});
示例:
如果鼠标移动速度超过 “clock”,那么不会发生任何事件,如果速度很慢或者在它们上面停下来,那么就会有一个工具提示。
请注意:当光标在 clock 子元素之间移动时,工具提示不会“一闪而过(blink)”。
算法看起来很简单:
- 将
onmouseover/out
处理器放在元素上。也可以在这里使用onmouseenter/leave
,但它们并不常用,而且如果我们使用委托,它们就会无效。 - 当鼠标光标进入元素时,开始测量
mousemove
上的速度。 - 如果速度慢,则运行
over
。 - 之后如果离开了元素,而且
over
也被执行了,则运行out
。
问题是:“如何测量速度?”
第一个想法是:每 100ms
运行一次我们的函数,并测量前一个坐标和新坐标之间的距离。如果它很小,那么速度就很小。
不幸的是,在 JavaScript 中无法获取“当前鼠标坐标”。没有像 getCurrentMouseCoordinates()
这样的函数。
获取坐标的唯一方法是监听鼠标事件,就像 mousemove
。
因此我们可以在 mousemove
上设置一个处理器来跟踪坐标并记住它们。然后我们可以比较它们,每 100ms
比较一次。
P.S. 请注意:解决方案测试使用 dispatchEvent
来查看工具提示是否正确。