稳健地定位 tooltip 相当棘手,因为你不仅需要考虑目标元素的布局度量,还需要考虑浏览器窗口和 tooltip 本身的布局度量。

幸运的是,有一个专注于解决此问题的小型库,叫做 floating-ui。要使用它,首先导入所需的 API:

import {
computePosition,
autoPlacement,
offset,
shift
} from '@floating-ui/dom';

通常,你还需要将 @floating-ui/dom 添加到 package.json 中,但为了加快进度,这已经完成了。

现在用 floating-ui 库的代码替换定位代码。该库的 API 需要目标元素和 tooltip 元素,并提供了一系列选项来配置定位方式。它通过 Promise 返回 tooltip 的 x, y 位置。

show = () => {
this.style.cssText = '';
// 稳健定位
computePosition(this.target, this, {
strategy: 'fixed',
middleware: [
offset(this.offset),
shift(),
autoPlacement({allowedPlacements: ['top', 'bottom']})
],
}).then(({x, y}: {x: number, y: number}) => {
this.style.left = `${x}px`;
this.style.top = `${y}px`;
});
};
show = () => {
this.style.cssText = '';
// 稳健定位
computePosition(this.target, this, {
strategy: 'fixed',
middleware: [
offset(this.offset),
shift(),
autoPlacement({allowedPlacements: ['top', 'bottom']}),
],
}).then(({x, y}) => {
this.style.left = `${x}px`;
this.style.top = `${y}px`;
});
};

现在将指针移到靠近预览窗口底部的方框上。如果上方有更多空间,tooltip 应该显示在方框上方。