123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import Vue from "vue";
- import { computePosition, offset, flip, shift, arrow } from "@floating-ui/dom";
- let tooltipNode = null;
- let intervalId = null;
- function removeTooltip() {
- try {
- intervalId && clearInterval(intervalId);
- tooltipNode && document.body.removeChild(tooltipNode);
- } catch (e) {
- // console.log(
- // "尝试从DOM上移除tooltip元素失败,通常是因为已经在其他回调中被移除了,不需处理:",
- // e
- // );
- }
- }
- Vue.directive("tooltip", {
- bind: function (el, binding) {
- if (!binding.value) {
- return;
- }
- el.addEventListener(
- "mouseenter",
- function (e) {
- tooltipNode = document.createElement("div");
- tooltipNode.style.position = "fixed";
- tooltipNode.style.zIndex = 100;
- tooltipNode.style.backgroundColor = "#191A1C";
- tooltipNode.style.border = "1px solid rgba(151, 151, 151, 0.2)";
- tooltipNode.style.borderRadius = "3px";
- tooltipNode.style.border = "1px solid rgba(151, 151, 151, 0.2)";
- tooltipNode.style.boxShadow = "0px 2px 12px 0px rgba(0, 0, 0, 0.06)";
- tooltipNode.style.padding = "8px 8px";
- tooltipNode.style.fontSize = "12px";
- tooltipNode.style.cursor = "default";
- tooltipNode.style.pointerEvents = "none";
- tooltipNode.style.wordBreak = "keep-all";
- tooltipNode.style.whiteSpace = "pre";
- tooltipNode.style.fontSize = "12px";
- tooltipNode.style.lineHeight = "17px";
- tooltipNode.style.color = "rgba(255, 255, 255, 0.6)";
- tooltipNode.innerText = binding.value;
- const arrowNode = document.createElement("div");
- arrowNode.style.position = "absolute";
- arrowNode.style.backgroundColor = "inherit";
- arrowNode.style.boxSizing = "border-box";
- arrowNode.style.width = "12px";
- arrowNode.style.height = "12px";
- arrowNode.style.border = "1px solid transparent";
- arrowNode.style.borderRight = "inherit";
- arrowNode.style.borderBottom = "inherit";
- arrowNode.style.transform = "rotate(45deg)";
- tooltipNode.appendChild(arrowNode);
- document.body.appendChild(tooltipNode);
- computePosition(el, tooltipNode, {
- placement: "top",
- middleware: [
- offset(13),
- flip(),
- shift({ padding: 12 }),
- arrow({
- element: arrowNode,
- padding: 3,
- }),
- ],
- })
- .then(({ x, y, placement, middlewareData }) => {
- Object.assign(tooltipNode.style, {
- left: `${x}px`,
- top: `${y}px`,
- });
- const { x: arrowX, y: arrowY } = middlewareData.arrow;
- const staticSide = {
- top: "bottom",
- right: "left",
- bottom: "top",
- left: "right",
- }[placement.split("-")[0]];
- Object.assign(arrowNode.style, {
- left: arrowX != null ? `${arrowX}px` : "",
- [staticSide]: "-6px",
- });
- })
- .catch((err) => {
- console.log(
- "计算tooltip位置时出现异常,可能因为目标元素已经被卸载。"
- );
- });
- intervalId = setInterval(() => {
- if (!document.contains(el)) {
- removeTooltip();
- }
- }, 300);
- },
- {
- passive: false,
- }
- );
- el.addEventListener("mouseleave", removeTooltip);
- el.addEventListener("mousedown", removeTooltip);
- el.addEventListener("keydown", removeTooltip);
- el.addEventListener("scroll", removeTooltip);
- el.addEventListener("dragstart", removeTooltip);
- el.addEventListener("dragstart", removeTooltip);
- el.addEventListener("dragleave", removeTooltip);
- },
- });
|