[我基本上想要实现的是监听文档中附加的'mousemove'事件,并且当我将鼠标悬停在元素上时,我检查它是否溢出了文本,并且是否将其截断并将title属性添加到具有全文本的目标元素因此,当用户将鼠标悬停在其上时,浏览器会显示带有此文本的默认工具提示。
此逻辑本身可以很好地工作,但存在重大缺陷。因为我在其中使用getComputedStyle(),所以它会破坏我的应用程序的性能。
为了解决这个问题,我尝试使用RxJS去抖动,并且效果很好。但是,如果用户快速移动鼠标然后停下,以便仅发射该元素的1个事件,则将工具提示添加到DOM,但未显示。
据我所知,从浏览器的角度来看,一切正常,因为当用户将鼠标悬停在元素上时,尚无标题,一旦添加,用户就不再移动鼠标,因此不会显示工具提示。
fromEvent(document, 'mouseenter')
.pipe(
debounceTime(20),
tap(($event: Event) => {
this.addTooltip($event);
})
)
.subscribe();
问题是,有人知道如何解决此问题吗?
[嗯,我想您可以尝试使用mousemove
方法在代码上触发Element.dispatchEvent()
事件。我已经尝试在[stackblitz demo]中做一些示例(是的,它是有角度的,但是我没有使用Andy的角度功能,除了关注标记markup-javascript-css =>之外,其他所有东西都是纯JavaScript)。基本上我所做的是:
<p title="house">
Start editing to see some magic happen :)
</p>
private elementWithListenerAdded = new Set();
...
fromEvent(document, "mousemove")
.pipe(
debounceTime(20),
tap(($event: MouseEvent) => {
this.addTooltip($event);
})
)
.subscribe();
...
addTooltip(evt: MouseEvent) {
const $tag = evt.target;
// I'm assuming that you don't want any tooltip on
// header, HTML or body tags
if (
($tag as any).tagName === "HEADER" ||
($tag as any).tagName === "HTML" ||
($tag as any).tagName === "BODY" ||
this.elementWithListenerAdded.has($tag)
) {
return;
}
const elementWithListenerAdded = this.elementWithListenerAdded;
// track the elements that already has a title modified
elementWithListenerAdded.add($tag);
// remove the event listener when the mouse leave the element
// and restore the original title
const originalTitle = ($tag as any).getAttribute("title");
function removeEventListener() {
$tag.removeEventListener("mouseleave", this);
elementWithListenerAdded.delete($tag);
($tag as any).setAttribute("title", originalTitle);
}
$tag.addEventListener("mouseleave", removeEventListener);
($tag as any).setAttribute("title", "just a test");
($tag as any).dispatchEvent(
new MouseEvent("mousemove", {
bubbles: true,
cancelable: true,
view: window
})
);
}