回到课程

“智能”工具提示

重要程度: 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();
  }
});

示例:

如果你将鼠标快速地从“时钟”上移动过去,那么什么都不会发生,如果你使用鼠标在“时钟”上慢慢移动,或者停在“时钟”上,则会出现一个工具提示。

请注意:当鼠标指针在“时钟”的元素之间移动时,工具提示不会“闪烁”

打开带有测试的沙箱。

算法看起来很简单:

  1. onmouseover/out 处理程序放在元素上。在这里也可以使用 onmouseenter/leave,但是它们的通用性较差,如果我们想引入事件委托时,它则无法使用。
  2. 当鼠标指针进入元素时,开始测量 mousemove 上的速度。
  3. 如果速度慢,则运行 over
  4. 当我们的鼠标指针要移出元素,并且 over 也执行了,则会运行 out

但是如何测量速度?

第一个想法是:每 100ms 运行一次函数,并测量前坐标和新坐标之间的距离。如果很小,那么速度就很小。

不幸的是,在 JavaScript 中无法获取“鼠标当前坐标”。没有像 getCurrentMouseCoordinates() 这样的函数。

获取坐标的唯一方法是监听例如 mousemove 这样的鼠标事件。

因此,我们可以在 mousemove 上设置一个处理程序来跟踪坐标并记住它们。然后我每 100ms 比较一次。

P.S. 请注意:解决方案测试使用 dispatchEvent 来检查工具提示是否正确。

使用沙箱的测试功能打开解决方案。