“智能”工具提示
重要程度: 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();
}
});
示例:
如果你将鼠标快速地从“时钟”上移动过去,那么什么都不会发生,如果你使用鼠标在“时钟”上慢慢移动,或者停在“时钟”上,则会出现一个工具提示。
请注意:当鼠标指针在“时钟”的元素之间移动时,工具提示不会“闪烁”
算法看起来很简单:
- 将
onmouseover/out
处理程序放在元素上。在这里也可以使用onmouseenter/leave
,但是它们的通用性较差,如果我们想引入事件委托时,它则无法使用。 - 当鼠标指针进入元素时,开始测量
mousemove
上的速度。 - 如果速度慢,则运行
over
。 - 当我们的鼠标指针要移出元素,并且
over
也执行了,则会运行out
。
但是如何测量速度?
第一个想法是:每 100ms
运行一次函数,并测量前坐标和新坐标之间的距离。如果很小,那么速度就很小。
不幸的是,在 JavaScript 中无法获取“鼠标当前坐标”。没有像 getCurrentMouseCoordinates()
这样的函数。
获取坐标的唯一方法是监听例如 mousemove
这样的鼠标事件。
因此,我们可以在 mousemove
上设置一个处理程序来跟踪坐标并记住它们。然后我每 100ms
比较一次。
P.S. 请注意:解决方案测试使用 dispatchEvent
来检查工具提示是否正确。